[Perf] TeactN: Get rid of redundant iterations for global actions
This commit is contained in:
parent
d12c9d384d
commit
3ef7136621
10
src/App.tsx
10
src/App.tsx
@ -1,7 +1,7 @@
|
|||||||
import { FC, useEffect } from './lib/teact/teact';
|
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 { INACTIVE_MARKER, PAGE_TITLE } from './config';
|
||||||
import { pick } from './util/iteratees';
|
import { pick } from './util/iteratees';
|
||||||
@ -17,9 +17,10 @@ import { hasStoredSession } from './util/sessions';
|
|||||||
// import Test from './components/test/TestNoRedundancy';
|
// import Test from './components/test/TestNoRedundancy';
|
||||||
|
|
||||||
type StateProps = Pick<GlobalState, 'authState'>;
|
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);
|
const [isInactive, markInactive] = useFlag(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -67,5 +68,4 @@ function renderMain() {
|
|||||||
|
|
||||||
export default withGlobal(
|
export default withGlobal(
|
||||||
(global): StateProps => pick(global, ['authState']),
|
(global): StateProps => pick(global, ['authState']),
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['disconnect']),
|
|
||||||
)(App);
|
)(App);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import React, { FC, useEffect, memo } from '../../lib/teact/teact';
|
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 '../../modules/actions/initial';
|
||||||
import { pick } from '../../util/iteratees';
|
import { pick } from '../../util/iteratees';
|
||||||
@ -19,11 +19,14 @@ import AuthQrCode from './AuthQrCode';
|
|||||||
import './Auth.scss';
|
import './Auth.scss';
|
||||||
|
|
||||||
type StateProps = Pick<GlobalState, 'authState'>;
|
type StateProps = Pick<GlobalState, 'authState'>;
|
||||||
type DispatchProps = Pick<GlobalActions, 'reset' | 'initApi' | 'returnToAuthPhoneNumber' | 'goToAuthQrCode'>;
|
|
||||||
|
|
||||||
const Auth: FC<StateProps & DispatchProps> = ({
|
const Auth: FC<StateProps> = ({
|
||||||
authState, reset, initApi, returnToAuthPhoneNumber, goToAuthQrCode,
|
authState,
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
reset, initApi, returnToAuthPhoneNumber, goToAuthQrCode,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
reset();
|
reset();
|
||||||
initApi();
|
initApi();
|
||||||
@ -73,5 +76,4 @@ const Auth: FC<StateProps & DispatchProps> = ({
|
|||||||
|
|
||||||
export default memo(withGlobal(
|
export default memo(withGlobal(
|
||||||
(global): StateProps => pick(global, ['authState']),
|
(global): StateProps => pick(global, ['authState']),
|
||||||
(global, actions): DispatchProps => pick(actions, ['reset', 'initApi', 'returnToAuthPhoneNumber', 'goToAuthQrCode']),
|
|
||||||
)(Auth));
|
)(Auth));
|
||||||
|
|||||||
@ -2,8 +2,8 @@ import { FormEvent } from 'react';
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useState, useEffect, useCallback, memo, useRef,
|
FC, useState, useEffect, useCallback, memo, useRef,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { IS_TOUCH_ENV } from '../../util/environment';
|
import { IS_TOUCH_ENV } from '../../util/environment';
|
||||||
import { pick } from '../../util/iteratees';
|
import { pick } from '../../util/iteratees';
|
||||||
@ -16,21 +16,21 @@ import Loading from '../ui/Loading';
|
|||||||
import TrackingMonkey from '../common/TrackingMonkey';
|
import TrackingMonkey from '../common/TrackingMonkey';
|
||||||
|
|
||||||
type StateProps = Pick<GlobalState, 'authPhoneNumber' | 'authIsCodeViaApp' | 'authIsLoading' | 'authError'>;
|
type StateProps = Pick<GlobalState, 'authPhoneNumber' | 'authIsCodeViaApp' | 'authIsLoading' | 'authError'>;
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'setAuthCode' | 'returnToAuthPhoneNumber' | 'clearAuthError'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const CODE_LENGTH = 5;
|
const CODE_LENGTH = 5;
|
||||||
|
|
||||||
const AuthCode: FC<StateProps & DispatchProps> = ({
|
const AuthCode: FC<StateProps> = ({
|
||||||
authPhoneNumber,
|
authPhoneNumber,
|
||||||
authIsCodeViaApp,
|
authIsCodeViaApp,
|
||||||
authIsLoading,
|
authIsLoading,
|
||||||
authError,
|
authError,
|
||||||
setAuthCode,
|
|
||||||
returnToAuthPhoneNumber,
|
|
||||||
clearAuthError,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
setAuthCode,
|
||||||
|
returnToAuthPhoneNumber,
|
||||||
|
clearAuthError,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
@ -120,9 +120,4 @@ const AuthCode: FC<StateProps & DispatchProps> = ({
|
|||||||
|
|
||||||
export default memo(withGlobal(
|
export default memo(withGlobal(
|
||||||
(global): StateProps => pick(global, ['authPhoneNumber', 'authIsCodeViaApp', 'authIsLoading', 'authError']),
|
(global): StateProps => pick(global, ['authPhoneNumber', 'authIsCodeViaApp', 'authIsLoading', 'authError']),
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'setAuthCode',
|
|
||||||
'returnToAuthPhoneNumber',
|
|
||||||
'clearAuthError',
|
|
||||||
]),
|
|
||||||
)(AuthCode));
|
)(AuthCode));
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useState,
|
FC, memo, useCallback, useState,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { pick } from '../../util/iteratees';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
@ -12,11 +12,12 @@ import MonkeyPassword from '../common/PasswordMonkey';
|
|||||||
import PasswordForm from '../common/PasswordForm';
|
import PasswordForm from '../common/PasswordForm';
|
||||||
|
|
||||||
type StateProps = Pick<GlobalState, 'authIsLoading' | 'authError' | 'authHint'>;
|
type StateProps = Pick<GlobalState, 'authIsLoading' | 'authError' | 'authHint'>;
|
||||||
type DispatchProps = Pick<GlobalActions, 'setAuthPassword' | 'clearAuthError'>;
|
|
||||||
|
|
||||||
const AuthPassword: FC<StateProps & DispatchProps> = ({
|
const AuthPassword: FC<StateProps> = ({
|
||||||
authIsLoading, authError, authHint, setAuthPassword, clearAuthError,
|
authIsLoading, authError, authHint,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { setAuthPassword, clearAuthError } = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const [showPassword, setShowPassword] = useState(false);
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
|
||||||
@ -50,5 +51,4 @@ const AuthPassword: FC<StateProps & DispatchProps> = ({
|
|||||||
|
|
||||||
export default memo(withGlobal(
|
export default memo(withGlobal(
|
||||||
(global): StateProps => pick(global, ['authIsLoading', 'authError', 'authHint']),
|
(global): StateProps => pick(global, ['authIsLoading', 'authError', 'authHint']),
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['setAuthPassword', 'clearAuthError']),
|
|
||||||
)(AuthPassword));
|
)(AuthPassword));
|
||||||
|
|||||||
@ -6,9 +6,9 @@ import monkeyPath from '../../assets/monkey.svg';
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useLayoutEffect, useRef, useState,
|
FC, memo, useCallback, useEffect, useLayoutEffect, useRef, useState,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { LangCode } from '../../types';
|
||||||
import { ApiCountryCode } from '../../api/types';
|
import { ApiCountryCode } from '../../api/types';
|
||||||
|
|
||||||
@ -38,16 +38,12 @@ type StateProps = Pick<GlobalState, (
|
|||||||
language?: LangCode;
|
language?: LangCode;
|
||||||
phoneCodeList: ApiCountryCode[];
|
phoneCodeList: ApiCountryCode[];
|
||||||
};
|
};
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'setAuthPhoneNumber' | 'setAuthRememberMe' | 'loadNearestCountry' | 'loadCountryList' | 'clearAuthError' |
|
|
||||||
'goToAuthQrCode' | 'setSettingOption'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const MIN_NUMBER_LENGTH = 7;
|
const MIN_NUMBER_LENGTH = 7;
|
||||||
|
|
||||||
let isPreloadInitiated = false;
|
let isPreloadInitiated = false;
|
||||||
|
|
||||||
const AuthPhoneNumber: FC<StateProps & DispatchProps> = ({
|
const AuthPhoneNumber: FC<StateProps> = ({
|
||||||
connectionState,
|
connectionState,
|
||||||
authState,
|
authState,
|
||||||
authPhoneNumber,
|
authPhoneNumber,
|
||||||
@ -58,14 +54,17 @@ const AuthPhoneNumber: FC<StateProps & DispatchProps> = ({
|
|||||||
authNearestCountry,
|
authNearestCountry,
|
||||||
phoneCodeList,
|
phoneCodeList,
|
||||||
language,
|
language,
|
||||||
setAuthPhoneNumber,
|
|
||||||
setAuthRememberMe,
|
|
||||||
loadNearestCountry,
|
|
||||||
loadCountryList,
|
|
||||||
clearAuthError,
|
|
||||||
goToAuthQrCode,
|
|
||||||
setSettingOption,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
setAuthPhoneNumber,
|
||||||
|
setAuthRememberMe,
|
||||||
|
loadNearestCountry,
|
||||||
|
loadCountryList,
|
||||||
|
clearAuthError,
|
||||||
|
goToAuthQrCode,
|
||||||
|
setSettingOption,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
@ -278,13 +277,4 @@ export default memo(withGlobal(
|
|||||||
phoneCodeList,
|
phoneCodeList,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'setAuthPhoneNumber',
|
|
||||||
'setAuthRememberMe',
|
|
||||||
'clearAuthError',
|
|
||||||
'loadNearestCountry',
|
|
||||||
'loadCountryList',
|
|
||||||
'goToAuthQrCode',
|
|
||||||
'setSettingOption',
|
|
||||||
]),
|
|
||||||
)(AuthPhoneNumber));
|
)(AuthPhoneNumber));
|
||||||
|
|||||||
@ -2,13 +2,12 @@ import QrCreator from 'qr-creator';
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useEffect, useRef, memo, useCallback,
|
FC, useEffect, useRef, memo, useCallback,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { LangCode } from '../../types';
|
||||||
|
|
||||||
import { DEFAULT_LANG_CODE } from '../../config';
|
import { DEFAULT_LANG_CODE } from '../../config';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import { setLanguage } from '../../util/langProvider';
|
import { setLanguage } from '../../util/langProvider';
|
||||||
import renderText from '../common/helpers/renderText';
|
import renderText from '../common/helpers/renderText';
|
||||||
import useLangString from '../../hooks/useLangString';
|
import useLangString from '../../hooks/useLangString';
|
||||||
@ -19,23 +18,25 @@ import { getSuggestedLanguage } from './helpers/getSuggestedLanguage';
|
|||||||
import Loading from '../ui/Loading';
|
import Loading from '../ui/Loading';
|
||||||
import Button from '../ui/Button';
|
import Button from '../ui/Button';
|
||||||
|
|
||||||
type StateProps = Pick<GlobalState, 'connectionState' | 'authState' | 'authQrCode'> & {
|
type StateProps =
|
||||||
language?: LangCode;
|
Pick<GlobalState, 'connectionState' | 'authState' | 'authQrCode'>
|
||||||
};
|
& {
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
language?: LangCode;
|
||||||
'returnToAuthPhoneNumber' | 'setSettingOption'
|
};
|
||||||
)>;
|
|
||||||
|
|
||||||
const DATA_PREFIX = 'tg://login?token=';
|
const DATA_PREFIX = 'tg://login?token=';
|
||||||
|
|
||||||
const AuthCode: FC<StateProps & DispatchProps> = ({
|
const AuthCode: FC<StateProps> = ({
|
||||||
connectionState,
|
connectionState,
|
||||||
authState,
|
authState,
|
||||||
authQrCode,
|
authQrCode,
|
||||||
language,
|
language,
|
||||||
returnToAuthPhoneNumber,
|
|
||||||
setSettingOption,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
returnToAuthPhoneNumber,
|
||||||
|
setSettingOption,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const suggestedLanguage = getSuggestedLanguage();
|
const suggestedLanguage = getSuggestedLanguage();
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
@ -118,7 +119,4 @@ export default memo(withGlobal(
|
|||||||
language,
|
language,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'returnToAuthPhoneNumber', 'setSettingOption',
|
|
||||||
]),
|
|
||||||
)(AuthCode));
|
)(AuthCode));
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { ChangeEvent } from 'react';
|
import { ChangeEvent } from 'react';
|
||||||
import React, { FC, useState, memo } from '../../lib/teact/teact';
|
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 { pick } from '../../util/iteratees';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
@ -12,11 +12,12 @@ import InputText from '../ui/InputText';
|
|||||||
import AvatarEditable from '../ui/AvatarEditable';
|
import AvatarEditable from '../ui/AvatarEditable';
|
||||||
|
|
||||||
type StateProps = Pick<GlobalState, 'authIsLoading' | 'authError'>;
|
type StateProps = Pick<GlobalState, 'authIsLoading' | 'authError'>;
|
||||||
type DispatchProps = Pick<GlobalActions, 'signUp' | 'clearAuthError' | 'uploadProfilePhoto'>;
|
|
||||||
|
|
||||||
const AuthRegister: FC<StateProps & DispatchProps> = ({
|
const AuthRegister: FC<StateProps> = ({
|
||||||
authIsLoading, authError, signUp, clearAuthError, uploadProfilePhoto,
|
authIsLoading, authError,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { signUp, clearAuthError, uploadProfilePhoto } = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const [isButtonShown, setIsButtonShown] = useState(false);
|
const [isButtonShown, setIsButtonShown] = useState(false);
|
||||||
const [croppedFile, setCroppedFile] = useState<File | undefined>();
|
const [croppedFile, setCroppedFile] = useState<File | undefined>();
|
||||||
@ -83,5 +84,4 @@ const AuthRegister: FC<StateProps & DispatchProps> = ({
|
|||||||
|
|
||||||
export default memo(withGlobal(
|
export default memo(withGlobal(
|
||||||
(global): StateProps => pick(global, ['authIsLoading', 'authError']),
|
(global): StateProps => pick(global, ['authIsLoading', 'authError']),
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['signUp', 'clearAuthError', 'uploadProfilePhoto']),
|
|
||||||
)(AuthRegister));
|
)(AuthRegister));
|
||||||
|
|||||||
@ -2,13 +2,11 @@ import { GroupCallParticipant } from '../../lib/secret-sauce';
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useEffect,
|
FC, memo, useEffect,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { ApiGroupCall } from '../../api/types';
|
||||||
|
|
||||||
import { selectActiveGroupCall, selectGroupCallParticipant } from '../../modules/selectors/calls';
|
import { selectActiveGroupCall, selectGroupCallParticipant } from '../../modules/selectors/calls';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
@ -20,14 +18,13 @@ type StateProps = {
|
|||||||
groupCall?: ApiGroupCall;
|
groupCall?: ApiGroupCall;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'toggleGroupCallPanel'>;
|
const ActiveCallHeader: FC<StateProps> = ({
|
||||||
|
|
||||||
const ActiveCallHeader: FC<StateProps & DispatchProps> = ({
|
|
||||||
groupCall,
|
groupCall,
|
||||||
meParticipant,
|
meParticipant,
|
||||||
isGroupCallPanelHidden,
|
isGroupCallPanelHidden,
|
||||||
toggleGroupCallPanel,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { toggleGroupCallPanel } = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -61,7 +58,4 @@ export default memo(withGlobal(
|
|||||||
meParticipant: selectGroupCallParticipant(global, global.groupCalls.activeGroupCallId!, global.currentUserId!),
|
meParticipant: selectGroupCallParticipant(global, global.groupCalls.activeGroupCallId!, global.currentUserId!),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions) => pick(actions, [
|
|
||||||
'toggleGroupCallPanel',
|
|
||||||
]),
|
|
||||||
)(ActiveCallHeader));
|
)(ActiveCallHeader));
|
||||||
|
|||||||
@ -1,9 +1,5 @@
|
|||||||
import React, { FC, memo, useState } from '../../lib/teact/teact';
|
import React, { FC, memo, useState } 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 ConfirmDialog from '../ui/ConfirmDialog';
|
import ConfirmDialog from '../ui/ConfirmDialog';
|
||||||
import Checkbox from '../ui/Checkbox';
|
import Checkbox from '../ui/Checkbox';
|
||||||
@ -21,15 +17,16 @@ interface StateProps {
|
|||||||
channelTitle: string;
|
channelTitle: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'closeCallFallbackConfirm' | 'inviteToCallFallback'>;
|
const CallFallbackConfirm: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const CallFallbackConfirm: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
isOpen,
|
isOpen,
|
||||||
channelTitle,
|
channelTitle,
|
||||||
userFullName,
|
userFullName,
|
||||||
closeCallFallbackConfirm,
|
|
||||||
inviteToCallFallback,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
closeCallFallbackConfirm,
|
||||||
|
inviteToCallFallback,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const [shouldRemove, setShouldRemove] = useState(true);
|
const [shouldRemove, setShouldRemove] = useState(true);
|
||||||
const renderingUserFullName = useCurrentOrPrev(userFullName, true);
|
const renderingUserFullName = useCurrentOrPrev(userFullName, true);
|
||||||
|
|
||||||
@ -62,7 +59,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
channelTitle: selectCallFallbackChannelTitle(global),
|
channelTitle: selectCallFallbackChannelTitle(global),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'closeCallFallbackConfirm', 'inviteToCallFallback',
|
|
||||||
]),
|
|
||||||
)(CallFallbackConfirm));
|
)(CallFallbackConfirm));
|
||||||
|
|||||||
@ -5,10 +5,9 @@ import {
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useMemo, useRef, useState,
|
FC, memo, useCallback, useEffect, useMemo, useRef, useState,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../../lib/teact/teactn';
|
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
|
||||||
import '../../../modules/actions/calls';
|
import '../../../modules/actions/calls';
|
||||||
|
|
||||||
import { GlobalActions } from '../../../global/types';
|
|
||||||
import { IAnchorPosition } from '../../../types';
|
import { IAnchorPosition } from '../../../types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -17,7 +16,6 @@ import {
|
|||||||
IS_REQUEST_FULLSCREEN_SUPPORTED,
|
IS_REQUEST_FULLSCREEN_SUPPORTED,
|
||||||
IS_SINGLE_COLUMN_LAYOUT,
|
IS_SINGLE_COLUMN_LAYOUT,
|
||||||
} from '../../../util/environment';
|
} from '../../../util/environment';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import {
|
import {
|
||||||
selectGroupCall,
|
selectGroupCall,
|
||||||
@ -59,12 +57,7 @@ type StateProps = {
|
|||||||
participants: Record<string, TypeGroupCallParticipant>;
|
participants: Record<string, TypeGroupCallParticipant>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
const GroupCall: FC<OwnProps & StateProps> = ({
|
||||||
'toggleGroupCallVideo' | 'leaveGroupCall' | 'toggleGroupCallPresentation' | 'toggleGroupCallPanel' |
|
|
||||||
'connectToActiveGroupCall' | 'playGroupCallSound'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const GroupCall: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
groupCallId,
|
groupCallId,
|
||||||
isGroupCallPanelHidden,
|
isGroupCallPanelHidden,
|
||||||
connectionState,
|
connectionState,
|
||||||
@ -74,13 +67,16 @@ const GroupCall: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
isAdmin,
|
isAdmin,
|
||||||
participants,
|
participants,
|
||||||
|
|
||||||
toggleGroupCallVideo,
|
|
||||||
toggleGroupCallPresentation,
|
|
||||||
leaveGroupCall,
|
|
||||||
toggleGroupCallPanel,
|
|
||||||
connectToActiveGroupCall,
|
|
||||||
playGroupCallSound,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
toggleGroupCallVideo,
|
||||||
|
toggleGroupCallPresentation,
|
||||||
|
leaveGroupCall,
|
||||||
|
toggleGroupCallPanel,
|
||||||
|
connectToActiveGroupCall,
|
||||||
|
playGroupCallSound,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
@ -411,12 +407,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
participants,
|
participants,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'toggleGroupCallVideo',
|
|
||||||
'leaveGroupCall',
|
|
||||||
'toggleGroupCallPresentation',
|
|
||||||
'toggleGroupCallPanel',
|
|
||||||
'connectToActiveGroupCall',
|
|
||||||
'playGroupCallSound',
|
|
||||||
]),
|
|
||||||
)(GroupCall));
|
)(GroupCall));
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
import { GroupCallParticipant as TypeGroupCallParticipant } from '../../../lib/secret-sauce';
|
import { GroupCallParticipant as TypeGroupCallParticipant } from '../../../lib/secret-sauce';
|
||||||
import React, { FC, memo, useMemo } from '../../../lib/teact/teact';
|
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 useLang from '../../../hooks/useLang';
|
||||||
import { selectActiveGroupCall } from '../../../modules/selectors/calls';
|
import { selectActiveGroupCall } from '../../../modules/selectors/calls';
|
||||||
import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
|
import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
|
||||||
@ -22,15 +19,16 @@ type StateProps = {
|
|||||||
canInvite?: boolean;
|
canInvite?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'createGroupCallInviteLink' | 'loadMoreGroupCallParticipants'>;
|
const GroupCallParticipantList: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const GroupCallParticipantList: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
createGroupCallInviteLink,
|
|
||||||
loadMoreGroupCallParticipants,
|
|
||||||
participants,
|
participants,
|
||||||
participantsCount,
|
participantsCount,
|
||||||
openParticipantMenu,
|
openParticipantMenu,
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
createGroupCallInviteLink,
|
||||||
|
loadMoreGroupCallParticipants,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const participantsIds = useMemo(() => {
|
const participantsIds = useMemo(() => {
|
||||||
@ -82,8 +80,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
participantsCount: participantsCount || 0,
|
participantsCount: participantsCount || 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'createGroupCallInviteLink',
|
|
||||||
'loadMoreGroupCallParticipants',
|
|
||||||
]),
|
|
||||||
)(GroupCallParticipantList));
|
)(GroupCallParticipantList));
|
||||||
|
|||||||
@ -2,17 +2,15 @@ import { GroupCallParticipant } from '../../../lib/secret-sauce';
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useState,
|
FC, memo, useCallback, useEffect, useState,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../../lib/teact/teactn';
|
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
|
||||||
|
|
||||||
import { IAnchorPosition } from '../../../types';
|
import { IAnchorPosition } from '../../../types';
|
||||||
import { GlobalActions } from '../../../global/types';
|
|
||||||
|
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import useThrottle from '../../../hooks/useThrottle';
|
import useThrottle from '../../../hooks/useThrottle';
|
||||||
import useFlag from '../../../hooks/useFlag';
|
import useFlag from '../../../hooks/useFlag';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
import { selectIsAdminInActiveGroupCall } from '../../../modules/selectors/calls';
|
import { selectIsAdminInActiveGroupCall } from '../../../modules/selectors/calls';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import { GROUP_CALL_DEFAULT_VOLUME, GROUP_CALL_VOLUME_MULTIPLIER } from '../../../config';
|
import { GROUP_CALL_DEFAULT_VOLUME, GROUP_CALL_VOLUME_MULTIPLIER } from '../../../config';
|
||||||
|
|
||||||
import Menu from '../../ui/Menu';
|
import Menu from '../../ui/Menu';
|
||||||
@ -36,10 +34,6 @@ type StateProps = {
|
|||||||
isAdmin: boolean;
|
isAdmin: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'toggleGroupCallMute' | 'setGroupCallParticipantVolume' | 'toggleGroupCallPanel' | 'openChat' | 'requestToSpeak'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const VOLUME_ZERO = 0;
|
const VOLUME_ZERO = 0;
|
||||||
const VOLUME_LOW = 50;
|
const VOLUME_LOW = 50;
|
||||||
const VOLUME_MEDIUM = 100;
|
const VOLUME_MEDIUM = 100;
|
||||||
@ -49,19 +43,21 @@ const VOLUME_CHANGE_THROTTLE = 500;
|
|||||||
|
|
||||||
const SPEAKER_ICON_SIZE = 24;
|
const SPEAKER_ICON_SIZE = 24;
|
||||||
|
|
||||||
const GroupCallParticipantMenu: FC<OwnProps & StateProps & DispatchProps> = ({
|
const GroupCallParticipantMenu: FC<OwnProps & StateProps> = ({
|
||||||
participant,
|
participant,
|
||||||
closeDropdown,
|
closeDropdown,
|
||||||
isDropdownOpen,
|
isDropdownOpen,
|
||||||
anchor,
|
anchor,
|
||||||
|
|
||||||
isAdmin,
|
isAdmin,
|
||||||
toggleGroupCallMute,
|
|
||||||
setGroupCallParticipantVolume,
|
|
||||||
toggleGroupCallPanel,
|
|
||||||
openChat,
|
|
||||||
requestToSpeak,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
toggleGroupCallMute,
|
||||||
|
setGroupCallParticipantVolume,
|
||||||
|
toggleGroupCallPanel,
|
||||||
|
openChat,
|
||||||
|
requestToSpeak,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const [isDeleteUserModalOpen, openDeleteUserModal, closeDeleteUserModal] = useFlag();
|
const [isDeleteUserModalOpen, openDeleteUserModal, closeDeleteUserModal] = useFlag();
|
||||||
|
|
||||||
@ -229,11 +225,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
isAdmin: selectIsAdminInActiveGroupCall(global),
|
isAdmin: selectIsAdminInActiveGroupCall(global),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'setGroupCallParticipantVolume',
|
|
||||||
'toggleGroupCallMute',
|
|
||||||
'openChat',
|
|
||||||
'toggleGroupCallPanel',
|
|
||||||
'requestToSpeak',
|
|
||||||
]),
|
|
||||||
)(GroupCallParticipantMenu));
|
)(GroupCallParticipantMenu));
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useMemo,
|
FC, memo, useCallback, useEffect, useMemo,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ApiChat, ApiGroupCall, ApiUser } from '../../../api/types';
|
||||||
|
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import { selectChatGroupCall } from '../../../modules/selectors/calls';
|
import { selectChatGroupCall } from '../../../modules/selectors/calls';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import { selectChat } from '../../../modules/selectors';
|
import { selectChat } from '../../../modules/selectors';
|
||||||
@ -29,18 +27,19 @@ type StateProps = {
|
|||||||
chatsById: Record<string, ApiChat>;
|
chatsById: Record<string, ApiChat>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'joinGroupCall' | 'subscribeToGroupCallUpdates'>;
|
const GroupCallTopPane: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const GroupCallTopPane: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
chatId,
|
chatId,
|
||||||
isActive,
|
isActive,
|
||||||
groupCall,
|
groupCall,
|
||||||
hasPinnedOffset,
|
hasPinnedOffset,
|
||||||
joinGroupCall,
|
|
||||||
subscribeToGroupCallUpdates,
|
|
||||||
usersById,
|
usersById,
|
||||||
chatsById,
|
chatsById,
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
joinGroupCall,
|
||||||
|
subscribeToGroupCallUpdates,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const handleJoinGroupCall = useCallback(() => {
|
const handleJoinGroupCall = useCallback(() => {
|
||||||
@ -132,8 +131,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
&& (global.groupCalls.activeGroupCallId !== groupCall?.id),
|
&& (global.groupCalls.activeGroupCallId !== groupCall?.id),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions) => pick(actions, [
|
|
||||||
'joinGroupCall',
|
|
||||||
'subscribeToGroupCallUpdates',
|
|
||||||
]),
|
|
||||||
)(GroupCallTopPane));
|
)(GroupCallTopPane));
|
||||||
|
|||||||
@ -2,13 +2,10 @@ import { GroupCallConnectionState } from '../../../lib/secret-sauce';
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useEffect, useMemo, useRef, useState,
|
FC, memo, useEffect, useMemo, useRef, useState,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../../lib/teact/teactn';
|
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
|
||||||
|
|
||||||
import { GlobalActions } from '../../../global/types';
|
|
||||||
|
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import { vibrateShort } from '../../../util/vibrate';
|
import { vibrateShort } from '../../../util/vibrate';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import usePrevious from '../../../hooks/usePrevious';
|
import usePrevious from '../../../hooks/usePrevious';
|
||||||
import { selectActiveGroupCall, selectGroupCallParticipant } from '../../../modules/selectors/calls';
|
import { selectActiveGroupCall, selectGroupCallParticipant } from '../../../modules/selectors/calls';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
@ -27,22 +24,23 @@ type StateProps = {
|
|||||||
noAudioStream: boolean;
|
noAudioStream: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'toggleGroupCallMute' | 'requestToSpeak' | 'playGroupCallSound'>;
|
|
||||||
|
|
||||||
const REQUEST_TO_SPEAK_THROTTLE = 3000;
|
const REQUEST_TO_SPEAK_THROTTLE = 3000;
|
||||||
const HOLD_TO_SPEAK_TIME = 200;
|
const HOLD_TO_SPEAK_TIME = 200;
|
||||||
const ICON_SIZE = 48;
|
const ICON_SIZE = 48;
|
||||||
|
|
||||||
const MicrophoneButton: FC<StateProps & DispatchProps> = ({
|
const MicrophoneButton: FC<StateProps> = ({
|
||||||
noAudioStream,
|
noAudioStream,
|
||||||
canSelfUnmute,
|
canSelfUnmute,
|
||||||
isMuted,
|
isMuted,
|
||||||
hasRequestedToSpeak,
|
hasRequestedToSpeak,
|
||||||
connectionState,
|
connectionState,
|
||||||
toggleGroupCallMute,
|
|
||||||
requestToSpeak,
|
|
||||||
playGroupCallSound,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
toggleGroupCallMute,
|
||||||
|
requestToSpeak,
|
||||||
|
playGroupCallSound,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const muteMouseDownState = useRef('up');
|
const muteMouseDownState = useRef('up');
|
||||||
|
|
||||||
@ -179,9 +177,4 @@ export default memo(withGlobal(
|
|||||||
isMuted,
|
isMuted,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'toggleGroupCallMute',
|
|
||||||
'requestToSpeak',
|
|
||||||
'playGroupCallSound',
|
|
||||||
]),
|
|
||||||
)(MicrophoneButton));
|
)(MicrophoneButton));
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect,
|
FC, memo, useCallback, useEffect,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { ApiChat, ApiCountryCode, ApiUser } from '../../api/types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -13,7 +13,6 @@ import {
|
|||||||
getChatDescription, getChatLink, getHasAdminRight, isChatChannel, isUserId, isUserRightBanned, selectIsChatMuted,
|
getChatDescription, getChatLink, getHasAdminRight, isChatChannel, isUserId, isUserRightBanned, selectIsChatMuted,
|
||||||
} from '../../modules/helpers';
|
} from '../../modules/helpers';
|
||||||
import renderText from './helpers/renderText';
|
import renderText from './helpers/renderText';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import { copyTextToClipboard } from '../../util/clipboard';
|
import { copyTextToClipboard } from '../../util/clipboard';
|
||||||
import { formatPhoneNumberWithCode } from '../../util/phoneNumber';
|
import { formatPhoneNumberWithCode } from '../../util/phoneNumber';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
@ -26,17 +25,17 @@ type OwnProps = {
|
|||||||
forceShowSelf?: boolean;
|
forceShowSelf?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps = {
|
type StateProps =
|
||||||
user?: ApiUser;
|
{
|
||||||
chat?: ApiChat;
|
user?: ApiUser;
|
||||||
canInviteUsers?: boolean;
|
chat?: ApiChat;
|
||||||
isMuted?: boolean;
|
canInviteUsers?: boolean;
|
||||||
phoneCodeList: ApiCountryCode[];
|
isMuted?: boolean;
|
||||||
} & Pick<GlobalState, 'lastSyncTime'>;
|
phoneCodeList: ApiCountryCode[];
|
||||||
|
}
|
||||||
|
& Pick<GlobalState, 'lastSyncTime'>;
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadFullUser' | 'updateChatMutedState' | 'showNotification'>;
|
const ChatExtra: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const ChatExtra: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
user,
|
user,
|
||||||
chat,
|
chat,
|
||||||
@ -44,10 +43,13 @@ const ChatExtra: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
canInviteUsers,
|
canInviteUsers,
|
||||||
isMuted,
|
isMuted,
|
||||||
phoneCodeList,
|
phoneCodeList,
|
||||||
loadFullUser,
|
|
||||||
showNotification,
|
|
||||||
updateChatMutedState,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadFullUser,
|
||||||
|
showNotification,
|
||||||
|
updateChatMutedState,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
id: userId,
|
id: userId,
|
||||||
fullInfo,
|
fullInfo,
|
||||||
@ -152,7 +154,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
lastSyncTime, phoneCodeList, chat, user, canInviteUsers, isMuted,
|
lastSyncTime, phoneCodeList, chat, user, canInviteUsers, isMuted,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'loadFullUser', 'updateChatMutedState', 'showNotification',
|
|
||||||
]),
|
|
||||||
)(ChatExtra));
|
)(ChatExtra));
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
import React, { FC, useCallback } from '../../lib/teact/teact';
|
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 buildClassName from '../../util/buildClassName';
|
||||||
|
|
||||||
import Link from '../ui/Link';
|
import Link from '../ui/Link';
|
||||||
@ -14,11 +11,11 @@ type OwnProps = {
|
|||||||
children: any;
|
children: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'openChat'>;
|
const ChatLink: FC<OwnProps> = ({
|
||||||
|
className, chatId, children,
|
||||||
const ChatLink: FC<OwnProps & DispatchProps> = ({
|
|
||||||
className, chatId, openChat, children,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { openChat } = getDispatch();
|
||||||
|
|
||||||
const handleClick = useCallback(() => {
|
const handleClick = useCallback(() => {
|
||||||
if (chatId) {
|
if (chatId) {
|
||||||
openChat({ id: chatId });
|
openChat({ id: chatId });
|
||||||
@ -34,7 +31,4 @@ const ChatLink: FC<OwnProps & DispatchProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withGlobal<OwnProps>(
|
export default ChatLink;
|
||||||
undefined,
|
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['openChat']),
|
|
||||||
)(ChatLink);
|
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import React, { FC, useCallback, memo } from '../../lib/teact/teact';
|
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 { ApiChat } from '../../api/types';
|
||||||
import { GlobalActions } from '../../global/types';
|
|
||||||
|
|
||||||
import { selectIsChatWithSelf, selectUser } from '../../modules/selectors';
|
import { selectIsChatWithSelf, selectUser } from '../../modules/selectors';
|
||||||
import {
|
import {
|
||||||
@ -15,7 +14,6 @@ import {
|
|||||||
isChatChannel,
|
isChatChannel,
|
||||||
getChatTitle,
|
getChatTitle,
|
||||||
} from '../../modules/helpers';
|
} from '../../modules/helpers';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
import renderText from './helpers/renderText';
|
import renderText from './helpers/renderText';
|
||||||
|
|
||||||
@ -44,11 +42,7 @@ type StateProps = {
|
|||||||
contactName?: string;
|
contactName?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
const DeleteChatModal: FC<OwnProps & StateProps> = ({
|
||||||
'leaveChannel' | 'deleteHistory' | 'deleteChannel' | 'deleteChatUser' | 'blockContact'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const DeleteChatModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
isOpen,
|
isOpen,
|
||||||
chat,
|
chat,
|
||||||
isChannel,
|
isChannel,
|
||||||
@ -62,12 +56,15 @@ const DeleteChatModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
contactName,
|
contactName,
|
||||||
onClose,
|
onClose,
|
||||||
onCloseAnimationEnd,
|
onCloseAnimationEnd,
|
||||||
leaveChannel,
|
|
||||||
deleteHistory,
|
|
||||||
deleteChannel,
|
|
||||||
deleteChatUser,
|
|
||||||
blockContact,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
leaveChannel,
|
||||||
|
deleteHistory,
|
||||||
|
deleteChannel,
|
||||||
|
deleteChatUser,
|
||||||
|
blockContact,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const chatTitle = getChatTitle(lang, chat);
|
const chatTitle = getChatTitle(lang, chat);
|
||||||
|
|
||||||
@ -217,6 +214,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
contactName,
|
contactName,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions,
|
|
||||||
['leaveChannel', 'deleteHistory', 'deleteChannel', 'deleteChatUser', 'blockContact']),
|
|
||||||
)(DeleteChatModal));
|
)(DeleteChatModal));
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
import React, { FC, useCallback, memo } from '../../lib/teact/teact';
|
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 { ApiMessage } from '../../api/types';
|
||||||
import { IAlbum } from '../../types';
|
import { IAlbum } from '../../types';
|
||||||
|
|
||||||
import { GlobalActions } from '../../global/types';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
selectAllowedMessageActions,
|
selectAllowedMessageActions,
|
||||||
selectChat,
|
selectChat,
|
||||||
@ -20,7 +18,6 @@ import {
|
|||||||
isChatSuperGroup,
|
isChatSuperGroup,
|
||||||
} from '../../modules/helpers';
|
} from '../../modules/helpers';
|
||||||
import renderText from './helpers/renderText';
|
import renderText from './helpers/renderText';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
import Modal from '../ui/Modal';
|
import Modal from '../ui/Modal';
|
||||||
@ -41,9 +38,7 @@ type StateProps = {
|
|||||||
willDeleteForAll?: boolean;
|
willDeleteForAll?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'deleteMessages' | 'deleteScheduledMessages'>;
|
const DeleteMessageModal: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const DeleteMessageModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
isOpen,
|
isOpen,
|
||||||
isSchedule,
|
isSchedule,
|
||||||
message,
|
message,
|
||||||
@ -53,9 +48,12 @@ const DeleteMessageModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
willDeleteForCurrentUserOnly,
|
willDeleteForCurrentUserOnly,
|
||||||
willDeleteForAll,
|
willDeleteForAll,
|
||||||
onClose,
|
onClose,
|
||||||
deleteMessages,
|
|
||||||
deleteScheduledMessages,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
deleteMessages,
|
||||||
|
deleteScheduledMessages,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const handleDeleteMessageForAll = useCallback(() => {
|
const handleDeleteMessageForAll = useCallback(() => {
|
||||||
const messageIds = album?.messages
|
const messageIds = album?.messages
|
||||||
? album.messages.map(({ id }) => id)
|
? album.messages.map(({ id }) => id)
|
||||||
@ -129,7 +127,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
willDeleteForAll,
|
willDeleteForAll,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'deleteMessages', 'deleteScheduledMessages',
|
|
||||||
]),
|
|
||||||
)(DeleteMessageModal));
|
)(DeleteMessageModal));
|
||||||
|
|||||||
@ -1,13 +1,11 @@
|
|||||||
import React, { FC, useCallback } from '../../lib/teact/teact';
|
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 { ApiGroupCall } from '../../api/types';
|
||||||
|
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
|
|
||||||
import Link from '../ui/Link';
|
import Link from '../ui/Link';
|
||||||
|
import { getDispatch } from '../../lib/teact/teactn';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
@ -15,11 +13,11 @@ type OwnProps = {
|
|||||||
children: any;
|
children: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'joinGroupCall'>;
|
const GroupCallLink: FC<OwnProps> = ({
|
||||||
|
className, groupCall, children,
|
||||||
const GroupCallLink: FC<OwnProps & DispatchProps> = ({
|
|
||||||
className, groupCall, joinGroupCall, children,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { joinGroupCall } = getDispatch();
|
||||||
|
|
||||||
const handleClick = useCallback(() => {
|
const handleClick = useCallback(() => {
|
||||||
if (groupCall) {
|
if (groupCall) {
|
||||||
joinGroupCall({ id: groupCall.id, accessHash: groupCall.accessHash });
|
joinGroupCall({ id: groupCall.id, accessHash: groupCall.accessHash });
|
||||||
@ -35,7 +33,4 @@ const GroupCallLink: FC<OwnProps & DispatchProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withGlobal<OwnProps>(
|
export default GroupCallLink;
|
||||||
undefined,
|
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['joinGroupCall']),
|
|
||||||
)(GroupCallLink);
|
|
||||||
|
|||||||
@ -2,10 +2,10 @@ import { MouseEvent as ReactMouseEvent } from 'react';
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useEffect, useCallback, memo,
|
FC, useEffect, useCallback, memo,
|
||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../lib/teact/teactn';
|
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
|
||||||
|
|
||||||
import { ApiChat, ApiTypingStatus } from '../../api/types';
|
import { ApiChat, ApiTypingStatus } from '../../api/types';
|
||||||
import { GlobalActions, GlobalState } from '../../global/types';
|
import { GlobalState } from '../../global/types';
|
||||||
import { MediaViewerOrigin } from '../../types';
|
import { MediaViewerOrigin } from '../../types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -15,7 +15,6 @@ import {
|
|||||||
} from '../../modules/helpers';
|
} from '../../modules/helpers';
|
||||||
import { selectChat, selectChatMessages, selectChatOnlineCount } from '../../modules/selectors';
|
import { selectChat, selectChatMessages, selectChatOnlineCount } from '../../modules/selectors';
|
||||||
import renderText from './helpers/renderText';
|
import renderText from './helpers/renderText';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import useLang, { LangFn } from '../../hooks/useLang';
|
import useLang, { LangFn } from '../../hooks/useLang';
|
||||||
|
|
||||||
import Avatar from './Avatar';
|
import Avatar from './Avatar';
|
||||||
@ -34,15 +33,15 @@ type OwnProps = {
|
|||||||
noRtl?: boolean;
|
noRtl?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps = {
|
type StateProps =
|
||||||
chat?: ApiChat;
|
{
|
||||||
onlineCount?: number;
|
chat?: ApiChat;
|
||||||
areMessagesLoaded: boolean;
|
onlineCount?: number;
|
||||||
} & Pick<GlobalState, 'lastSyncTime'>;
|
areMessagesLoaded: boolean;
|
||||||
|
}
|
||||||
|
& Pick<GlobalState, 'lastSyncTime'>;
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadFullChat' | 'openMediaViewer'>;
|
const GroupChatInfo: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const GroupChatInfo: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
typingStatus,
|
typingStatus,
|
||||||
avatarSize = 'medium',
|
avatarSize = 'medium',
|
||||||
withMediaViewer,
|
withMediaViewer,
|
||||||
@ -55,9 +54,12 @@ const GroupChatInfo: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
onlineCount,
|
onlineCount,
|
||||||
areMessagesLoaded,
|
areMessagesLoaded,
|
||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
loadFullChat,
|
|
||||||
openMediaViewer,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadFullChat,
|
||||||
|
openMediaViewer,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const isSuperGroup = chat && isChatSuperGroup(chat);
|
const isSuperGroup = chat && isChatSuperGroup(chat);
|
||||||
const { id: chatId, isMin, isRestricted } = chat || {};
|
const { id: chatId, isMin, isRestricted } = chat || {};
|
||||||
|
|
||||||
@ -164,5 +166,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
lastSyncTime, chat, onlineCount, areMessagesLoaded,
|
lastSyncTime, chat, onlineCount, areMessagesLoaded,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['loadFullChat', 'openMediaViewer']),
|
|
||||||
)(GroupChatInfo));
|
)(GroupChatInfo));
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
import React, { FC, useCallback } from '../../lib/teact/teact';
|
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 { ApiMessage } from '../../api/types';
|
||||||
|
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
|
|
||||||
import Link from '../ui/Link';
|
import Link from '../ui/Link';
|
||||||
@ -15,11 +13,11 @@ type OwnProps = {
|
|||||||
children: any;
|
children: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'focusMessage'>;
|
const MessageLink: FC<OwnProps> = ({
|
||||||
|
className, message, children,
|
||||||
const MessageLink: FC<OwnProps & DispatchProps> = ({
|
|
||||||
className, message, children, focusMessage,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { focusMessage } = getDispatch();
|
||||||
|
|
||||||
const handleMessageClick = useCallback((): void => {
|
const handleMessageClick = useCallback((): void => {
|
||||||
if (message) {
|
if (message) {
|
||||||
focusMessage({ chatId: message.chatId, messageId: message.id });
|
focusMessage({ chatId: message.chatId, messageId: message.id });
|
||||||
@ -35,7 +33,4 @@ const MessageLink: FC<OwnProps & DispatchProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withGlobal<OwnProps>(
|
export default MessageLink;
|
||||||
undefined,
|
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['focusMessage']),
|
|
||||||
)(MessageLink);
|
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
import React, { FC, useCallback, memo } from '../../lib/teact/teact';
|
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 { selectChat, selectIsChatWithSelf, selectUser } from '../../modules/selectors';
|
import { selectChat, selectIsChatWithSelf, selectUser } from '../../modules/selectors';
|
||||||
import {
|
import {
|
||||||
@ -12,7 +10,6 @@ import {
|
|||||||
isChatSuperGroup,
|
isChatSuperGroup,
|
||||||
isChatChannel,
|
isChatChannel,
|
||||||
} from '../../modules/helpers';
|
} from '../../modules/helpers';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
import renderText from './helpers/renderText';
|
import renderText from './helpers/renderText';
|
||||||
|
|
||||||
@ -36,9 +33,7 @@ type StateProps = {
|
|||||||
contactName?: string;
|
contactName?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'pinMessage'>;
|
const PinMessageModal: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const PinMessageModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
isOpen,
|
isOpen,
|
||||||
messageId,
|
messageId,
|
||||||
chatId,
|
chatId,
|
||||||
@ -48,8 +43,9 @@ const PinMessageModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
canPinForAll,
|
canPinForAll,
|
||||||
contactName,
|
contactName,
|
||||||
onClose,
|
onClose,
|
||||||
pinMessage,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { pinMessage } = getDispatch();
|
||||||
|
|
||||||
const handlePinMessageForAll = useCallback(() => {
|
const handlePinMessageForAll = useCallback(() => {
|
||||||
pinMessage({
|
pinMessage({
|
||||||
chatId, messageId, isUnpin: false,
|
chatId, messageId, isUnpin: false,
|
||||||
@ -124,5 +120,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
contactName,
|
contactName,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['pinMessage']),
|
|
||||||
)(PinMessageModal));
|
)(PinMessageModal));
|
||||||
|
|||||||
@ -2,16 +2,15 @@ import { MouseEvent as ReactMouseEvent } from 'react';
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useEffect, useCallback, memo,
|
FC, useEffect, useCallback, memo,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { ApiUser, ApiTypingStatus, ApiUserStatus } from '../../api/types';
|
||||||
import { GlobalActions, GlobalState } from '../../global/types';
|
import { GlobalState } from '../../global/types';
|
||||||
import { MediaViewerOrigin } from '../../types';
|
import { MediaViewerOrigin } from '../../types';
|
||||||
|
|
||||||
import { selectChatMessages, selectUser, selectUserStatus } from '../../modules/selectors';
|
import { selectChatMessages, selectUser, selectUserStatus } from '../../modules/selectors';
|
||||||
import { getUserFullName, getUserStatus, isUserOnline } from '../../modules/helpers';
|
import { getUserFullName, getUserStatus, isUserOnline } from '../../modules/helpers';
|
||||||
import renderText from './helpers/renderText';
|
import renderText from './helpers/renderText';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
import Avatar from './Avatar';
|
import Avatar from './Avatar';
|
||||||
@ -32,17 +31,17 @@ type OwnProps = {
|
|||||||
noRtl?: boolean;
|
noRtl?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps = {
|
type StateProps =
|
||||||
user?: ApiUser;
|
{
|
||||||
userStatus?: ApiUserStatus;
|
user?: ApiUser;
|
||||||
isSavedMessages?: boolean;
|
userStatus?: ApiUserStatus;
|
||||||
areMessagesLoaded: boolean;
|
isSavedMessages?: boolean;
|
||||||
serverTimeOffset: number;
|
areMessagesLoaded: boolean;
|
||||||
} & Pick<GlobalState, 'lastSyncTime'>;
|
serverTimeOffset: number;
|
||||||
|
}
|
||||||
|
& Pick<GlobalState, 'lastSyncTime'>;
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadFullUser' | 'openMediaViewer'>;
|
const PrivateChatInfo: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const PrivateChatInfo: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
typingStatus,
|
typingStatus,
|
||||||
avatarSize = 'medium',
|
avatarSize = 'medium',
|
||||||
status,
|
status,
|
||||||
@ -58,9 +57,12 @@ const PrivateChatInfo: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
areMessagesLoaded,
|
areMessagesLoaded,
|
||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
serverTimeOffset,
|
serverTimeOffset,
|
||||||
loadFullUser,
|
|
||||||
openMediaViewer,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadFullUser,
|
||||||
|
openMediaViewer,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const { id: userId } = user || {};
|
const { id: userId } = user || {};
|
||||||
const fullName = getUserFullName(user);
|
const fullName = getUserFullName(user);
|
||||||
|
|
||||||
@ -153,5 +155,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
lastSyncTime, user, userStatus, isSavedMessages, areMessagesLoaded, serverTimeOffset,
|
lastSyncTime, user, userStatus, isSavedMessages, areMessagesLoaded, serverTimeOffset,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['loadFullUser', 'openMediaViewer']),
|
|
||||||
)(PrivateChatInfo));
|
)(PrivateChatInfo));
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useEffect, useCallback, memo, useState,
|
FC, useEffect, useCallback, memo, useState,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { ApiUser, ApiChat, ApiUserStatus } from '../../api/types';
|
||||||
import { GlobalActions, GlobalState } from '../../global/types';
|
import { GlobalState } from '../../global/types';
|
||||||
import { MediaViewerOrigin } from '../../types';
|
import { MediaViewerOrigin } from '../../types';
|
||||||
|
|
||||||
import { IS_TOUCH_ENV } from '../../util/environment';
|
import { IS_TOUCH_ENV } from '../../util/environment';
|
||||||
@ -13,7 +13,6 @@ import {
|
|||||||
getUserFullName, getUserStatus, isChatChannel, isUserOnline,
|
getUserFullName, getUserStatus, isChatChannel, isUserOnline,
|
||||||
} from '../../modules/helpers';
|
} from '../../modules/helpers';
|
||||||
import renderText from './helpers/renderText';
|
import renderText from './helpers/renderText';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import { captureEvents, SwipeDirection } from '../../util/captureEvents';
|
import { captureEvents, SwipeDirection } from '../../util/captureEvents';
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
import usePhotosPreload from './hooks/usePhotosPreload';
|
import usePhotosPreload from './hooks/usePhotosPreload';
|
||||||
@ -30,18 +29,18 @@ type OwnProps = {
|
|||||||
forceShowSelf?: boolean;
|
forceShowSelf?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps = {
|
type StateProps =
|
||||||
user?: ApiUser;
|
{
|
||||||
userStatus?: ApiUserStatus;
|
user?: ApiUser;
|
||||||
chat?: ApiChat;
|
userStatus?: ApiUserStatus;
|
||||||
isSavedMessages?: boolean;
|
chat?: ApiChat;
|
||||||
animationLevel: 0 | 1 | 2;
|
isSavedMessages?: boolean;
|
||||||
serverTimeOffset: number;
|
animationLevel: 0 | 1 | 2;
|
||||||
} & Pick<GlobalState, 'connectionState'>;
|
serverTimeOffset: number;
|
||||||
|
}
|
||||||
|
& Pick<GlobalState, 'connectionState'>;
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadFullUser' | 'openMediaViewer'>;
|
const ProfileInfo: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const ProfileInfo: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
forceShowSelf,
|
forceShowSelf,
|
||||||
user,
|
user,
|
||||||
userStatus,
|
userStatus,
|
||||||
@ -50,9 +49,12 @@ const ProfileInfo: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
connectionState,
|
connectionState,
|
||||||
animationLevel,
|
animationLevel,
|
||||||
serverTimeOffset,
|
serverTimeOffset,
|
||||||
loadFullUser,
|
|
||||||
openMediaViewer,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadFullUser,
|
||||||
|
openMediaViewer,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const { id: userId } = user || {};
|
const { id: userId } = user || {};
|
||||||
@ -246,5 +248,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
serverTimeOffset,
|
serverTimeOffset,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['loadFullUser', 'openMediaViewer']),
|
|
||||||
)(ProfileInfo));
|
)(ProfileInfo));
|
||||||
|
|||||||
@ -3,13 +3,10 @@ import { ChangeEvent } from 'react';
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useState,
|
FC, memo, useCallback, useState,
|
||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../lib/teact/teactn';
|
import { getDispatch } from '../../lib/teact/teactn';
|
||||||
|
|
||||||
import { ApiReportReason } from '../../api/types';
|
import { ApiReportReason } from '../../api/types';
|
||||||
|
|
||||||
import { GlobalActions } from '../../global/types';
|
|
||||||
|
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
import Modal from '../ui/Modal';
|
import Modal from '../ui/Modal';
|
||||||
@ -23,15 +20,16 @@ export type OwnProps = {
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'reportMessages' | 'exitMessageSelectMode'>;
|
const ReportMessageModal: FC<OwnProps> = ({
|
||||||
|
|
||||||
const ReportMessageModal: FC<OwnProps & DispatchProps> = ({
|
|
||||||
isOpen,
|
isOpen,
|
||||||
messageIds,
|
messageIds,
|
||||||
reportMessages,
|
|
||||||
exitMessageSelectMode,
|
|
||||||
onClose,
|
onClose,
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
reportMessages,
|
||||||
|
exitMessageSelectMode,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const [selectedReason, setSelectedReason] = useState<ApiReportReason>('spam');
|
const [selectedReason, setSelectedReason] = useState<ApiReportReason>('spam');
|
||||||
const [description, setDescription] = useState('');
|
const [description, setDescription] = useState('');
|
||||||
|
|
||||||
@ -91,8 +89,4 @@ const ReportMessageModal: FC<OwnProps & DispatchProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(withGlobal<OwnProps>(
|
export default memo(ReportMessageModal);
|
||||||
undefined, (setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'reportMessages', 'exitMessageSelectMode',
|
|
||||||
]),
|
|
||||||
)(ReportMessageModal));
|
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
import React, { FC, useCallback, memo } from '../../lib/teact/teact';
|
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 useLang from '../../hooks/useLang';
|
||||||
import { selectChatMessage } from '../../modules/selectors';
|
import { selectChatMessage } from '../../modules/selectors';
|
||||||
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
|
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
|
||||||
@ -21,16 +18,17 @@ export type StateProps = {
|
|||||||
memberIds?: string[];
|
memberIds?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'openChat' | 'closeSeenByModal'>;
|
|
||||||
|
|
||||||
const CLOSE_ANIMATION_DURATION = 100;
|
const CLOSE_ANIMATION_DURATION = 100;
|
||||||
|
|
||||||
const SeenByModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
const SeenByModal: FC<OwnProps & StateProps> = ({
|
||||||
isOpen,
|
isOpen,
|
||||||
memberIds,
|
memberIds,
|
||||||
openChat,
|
|
||||||
closeSeenByModal,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
openChat,
|
||||||
|
closeSeenByModal,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const handleClick = useCallback((userId: string) => {
|
const handleClick = useCallback((userId: string) => {
|
||||||
@ -83,5 +81,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
memberIds: selectChatMessage(global, chatId, messageId)?.seenByUserIds,
|
memberIds: selectChatMessage(global, chatId, messageId)?.seenByUserIds,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['openChat', 'closeSeenByModal']),
|
|
||||||
)(SeenByModal));
|
)(SeenByModal));
|
||||||
|
|||||||
@ -1,13 +1,11 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useRef,
|
FC, memo, useCallback, useEffect, useRef,
|
||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../lib/teact/teactn';
|
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
|
||||||
|
|
||||||
import { ApiSticker, ApiStickerSet } from '../../api/types';
|
import { ApiSticker, ApiStickerSet } from '../../api/types';
|
||||||
import { GlobalActions } from '../../global/types';
|
|
||||||
|
|
||||||
import { STICKER_SIZE_MODAL } from '../../config';
|
import { STICKER_SIZE_MODAL } from '../../config';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import {
|
import {
|
||||||
selectChat, selectCurrentMessageList, selectStickerSet, selectStickerSetByShortName,
|
selectChat, selectCurrentMessageList, selectStickerSet, selectStickerSetByShortName,
|
||||||
} from '../../modules/selectors';
|
} from '../../modules/selectors';
|
||||||
@ -35,21 +33,22 @@ type StateProps = {
|
|||||||
stickerSet?: ApiStickerSet;
|
stickerSet?: ApiStickerSet;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadStickers' | 'toggleStickerSet' | 'sendMessage'>;
|
|
||||||
|
|
||||||
const INTERSECTION_THROTTLE = 200;
|
const INTERSECTION_THROTTLE = 200;
|
||||||
|
|
||||||
const StickerSetModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
const StickerSetModal: FC<OwnProps & StateProps> = ({
|
||||||
isOpen,
|
isOpen,
|
||||||
fromSticker,
|
fromSticker,
|
||||||
stickerSetShortName,
|
stickerSetShortName,
|
||||||
stickerSet,
|
stickerSet,
|
||||||
canSendStickers,
|
canSendStickers,
|
||||||
onClose,
|
onClose,
|
||||||
loadStickers,
|
|
||||||
toggleStickerSet,
|
|
||||||
sendMessage,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadStickers,
|
||||||
|
toggleStickerSet,
|
||||||
|
sendMessage,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
@ -153,9 +152,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
: undefined,
|
: undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'loadStickers',
|
|
||||||
'toggleStickerSet',
|
|
||||||
'sendMessage',
|
|
||||||
]),
|
|
||||||
)(StickerSetModal));
|
)(StickerSetModal));
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import React, { FC, useEffect } from '../../lib/teact/teact';
|
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 { 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 { getChatAvatarHash } from '../../modules/helpers/chats'; // Direct import for better module splitting
|
||||||
import useFlag from '../../hooks/useFlag';
|
import useFlag from '../../hooks/useFlag';
|
||||||
@ -12,7 +12,6 @@ import { preloadImage } from '../../util/files';
|
|||||||
import preloadFonts from '../../util/fonts';
|
import preloadFonts from '../../util/fonts';
|
||||||
import * as mediaLoader from '../../util/mediaLoader';
|
import * as mediaLoader from '../../util/mediaLoader';
|
||||||
import { Bundles, loadModule } from '../../util/moduleLoader';
|
import { Bundles, loadModule } from '../../util/moduleLoader';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
|
|
||||||
import './UiLoader.scss';
|
import './UiLoader.scss';
|
||||||
@ -28,14 +27,14 @@ type OwnProps = {
|
|||||||
children: any;
|
children: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps = Pick<GlobalState, 'uiReadyState' | 'shouldSkipHistoryAnimations'> & {
|
type StateProps =
|
||||||
hasCustomBackground?: boolean;
|
Pick<GlobalState, 'uiReadyState' | 'shouldSkipHistoryAnimations'>
|
||||||
hasCustomBackgroundColor: boolean;
|
& {
|
||||||
isRightColumnShown?: boolean;
|
hasCustomBackground?: boolean;
|
||||||
leftColumnWidth?: number;
|
hasCustomBackgroundColor: boolean;
|
||||||
};
|
isRightColumnShown?: boolean;
|
||||||
|
leftColumnWidth?: number;
|
||||||
type DispatchProps = Pick<GlobalActions, 'setIsUiReady'>;
|
};
|
||||||
|
|
||||||
const MAX_PRELOAD_DELAY = 700;
|
const MAX_PRELOAD_DELAY = 700;
|
||||||
const SECOND_STATE_DELAY = 1000;
|
const SECOND_STATE_DELAY = 1000;
|
||||||
@ -77,7 +76,7 @@ const preloadTasks = {
|
|||||||
authQrCode: preloadFonts,
|
authQrCode: preloadFonts,
|
||||||
};
|
};
|
||||||
|
|
||||||
const UiLoader: FC<OwnProps & StateProps & DispatchProps> = ({
|
const UiLoader: FC<OwnProps & StateProps> = ({
|
||||||
page,
|
page,
|
||||||
children,
|
children,
|
||||||
hasCustomBackground,
|
hasCustomBackground,
|
||||||
@ -85,8 +84,9 @@ const UiLoader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
isRightColumnShown,
|
isRightColumnShown,
|
||||||
shouldSkipHistoryAnimations,
|
shouldSkipHistoryAnimations,
|
||||||
leftColumnWidth,
|
leftColumnWidth,
|
||||||
setIsUiReady,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { setIsUiReady } = getDispatch();
|
||||||
|
|
||||||
const [isReady, markReady] = useFlag();
|
const [isReady, markReady] = useFlag();
|
||||||
const {
|
const {
|
||||||
shouldRender: shouldRenderMask, transitionClassNames,
|
shouldRender: shouldRenderMask, transitionClassNames,
|
||||||
@ -171,5 +171,4 @@ export default withGlobal<OwnProps>(
|
|||||||
leftColumnWidth: global.leftColumnWidth,
|
leftColumnWidth: global.leftColumnWidth,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['setIsUiReady']),
|
|
||||||
)(UiLoader);
|
)(UiLoader);
|
||||||
|
|||||||
@ -1,13 +1,11 @@
|
|||||||
import React, { FC, useCallback } from '../../lib/teact/teact';
|
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 { ApiChat, ApiUser } from '../../api/types';
|
||||||
|
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
|
|
||||||
import Link from '../ui/Link';
|
import Link from '../ui/Link';
|
||||||
|
import { getDispatch } from '../../lib/teact/teactn';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
@ -15,11 +13,11 @@ type OwnProps = {
|
|||||||
children: any;
|
children: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'openUserInfo'>;
|
const UserLink: FC<OwnProps> = ({
|
||||||
|
className, sender, children,
|
||||||
const UserLink: FC<OwnProps & DispatchProps> = ({
|
|
||||||
className, sender, openUserInfo, children,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { openUserInfo } = getDispatch();
|
||||||
|
|
||||||
const handleClick = useCallback(() => {
|
const handleClick = useCallback(() => {
|
||||||
if (sender) {
|
if (sender) {
|
||||||
openUserInfo({ id: sender.id });
|
openUserInfo({ id: sender.id });
|
||||||
@ -35,7 +33,4 @@ const UserLink: FC<OwnProps & DispatchProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withGlobal<OwnProps>(
|
export default UserLink;
|
||||||
undefined,
|
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['openUserInfo']),
|
|
||||||
)(UserLink);
|
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useCallback, memo, useMemo, useState,
|
FC, useCallback, memo, useMemo, useState,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { ApiChatFolder } from '../../api/types';
|
||||||
|
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
import Modal from '../ui/Modal';
|
import Modal from '../ui/Modal';
|
||||||
@ -25,17 +23,16 @@ type StateProps = {
|
|||||||
folderOrderedIds?: number[];
|
folderOrderedIds?: number[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'editChatFolders'>;
|
const ChatFolderModal: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const ChatFolderModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
isOpen,
|
isOpen,
|
||||||
chatId,
|
chatId,
|
||||||
foldersById,
|
foldersById,
|
||||||
folderOrderedIds,
|
folderOrderedIds,
|
||||||
onClose,
|
onClose,
|
||||||
onCloseAnimationEnd,
|
onCloseAnimationEnd,
|
||||||
editChatFolders,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { editChatFolders } = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const initialSelectedFolderIds = useMemo(() => {
|
const initialSelectedFolderIds = useMemo(() => {
|
||||||
@ -106,5 +103,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
folderOrderedIds,
|
folderOrderedIds,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['editChatFolders']),
|
|
||||||
)(ChatFolderModal));
|
)(ChatFolderModal));
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useRef, useState,
|
FC, memo, useCallback, useEffect, useRef, useState,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { LeftColumnContent, SettingsScreens } from '../../types';
|
||||||
|
|
||||||
import { LAYERS_ANIMATION_NAME } from '../../util/environment';
|
import { LAYERS_ANIMATION_NAME } from '../../util/environment';
|
||||||
import captureEscKeyListener from '../../util/captureEscKeyListener';
|
import captureEscKeyListener from '../../util/captureEscKeyListener';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import useFoldersReducer from '../../hooks/reducers/useFoldersReducer';
|
import useFoldersReducer from '../../hooks/reducers/useFoldersReducer';
|
||||||
import { useResize } from '../../hooks/useResize';
|
import { useResize } from '../../hooks/useResize';
|
||||||
|
|
||||||
@ -28,11 +26,6 @@ type StateProps = {
|
|||||||
leftColumnWidth?: number;
|
leftColumnWidth?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'setGlobalSearchQuery' | 'setGlobalSearchChatId' | 'resetChatCreation' | 'setGlobalSearchDate' |
|
|
||||||
'loadPasswordInfo' | 'clearTwoFaError' | 'setLeftColumnWidth' | 'resetLeftColumnWidth'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
enum ContentType {
|
enum ContentType {
|
||||||
Main,
|
Main,
|
||||||
// eslint-disable-next-line @typescript-eslint/no-shadow
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
@ -47,21 +40,24 @@ enum ContentType {
|
|||||||
const RENDER_COUNT = Object.keys(ContentType).length / 2;
|
const RENDER_COUNT = Object.keys(ContentType).length / 2;
|
||||||
const RESET_TRANSITION_DELAY_MS = 250;
|
const RESET_TRANSITION_DELAY_MS = 250;
|
||||||
|
|
||||||
const LeftColumn: FC<StateProps & DispatchProps> = ({
|
const LeftColumn: FC<StateProps> = ({
|
||||||
searchQuery,
|
searchQuery,
|
||||||
searchDate,
|
searchDate,
|
||||||
activeChatFolder,
|
activeChatFolder,
|
||||||
shouldSkipHistoryAnimations,
|
shouldSkipHistoryAnimations,
|
||||||
leftColumnWidth,
|
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
|
// eslint-disable-next-line no-null/no-null
|
||||||
const resizeRef = useRef<HTMLDivElement>(null);
|
const resizeRef = useRef<HTMLDivElement>(null);
|
||||||
const [content, setContent] = useState<LeftColumnContent>(LeftColumnContent.ChatList);
|
const [content, setContent] = useState<LeftColumnContent>(LeftColumnContent.ChatList);
|
||||||
@ -374,8 +370,4 @@ export default memo(withGlobal(
|
|||||||
searchQuery: query, searchDate: date, activeChatFolder, shouldSkipHistoryAnimations, leftColumnWidth,
|
searchQuery: query, searchDate: date, activeChatFolder, shouldSkipHistoryAnimations, leftColumnWidth,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'setGlobalSearchQuery', 'setGlobalSearchChatId', 'resetChatCreation', 'setGlobalSearchDate',
|
|
||||||
'loadPasswordInfo', 'clearTwoFaError', 'setLeftColumnWidth', 'resetLeftColumnWidth',
|
|
||||||
]),
|
|
||||||
)(LeftColumn));
|
)(LeftColumn));
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useLayoutEffect, useMemo, useRef,
|
FC, memo, useCallback, useLayoutEffect, useMemo, useRef,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../../lib/teact/teactn';
|
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
|
||||||
|
|
||||||
import useLang, { LangFn } from '../../../hooks/useLang';
|
import useLang, { LangFn } from '../../../hooks/useLang';
|
||||||
|
|
||||||
import { GlobalActions } from '../../../global/types';
|
|
||||||
import {
|
import {
|
||||||
ApiChat, ApiUser, ApiMessage, ApiMessageOutgoingStatus, ApiFormattedText, MAIN_THREAD_ID, ApiUserStatus,
|
ApiChat, ApiUser, ApiMessage, ApiMessageOutgoingStatus, ApiFormattedText, MAIN_THREAD_ID, ApiUserStatus,
|
||||||
} from '../../../api/types';
|
} from '../../../api/types';
|
||||||
@ -36,7 +35,6 @@ import { renderActionMessageText } from '../../common/helpers/renderActionMessag
|
|||||||
import renderText from '../../common/helpers/renderText';
|
import renderText from '../../common/helpers/renderText';
|
||||||
import { fastRaf } from '../../../util/schedulers';
|
import { fastRaf } from '../../../util/schedulers';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import useEnsureMessage from '../../../hooks/useEnsureMessage';
|
import useEnsureMessage from '../../../hooks/useEnsureMessage';
|
||||||
import useChatContextActions from '../../../hooks/useChatContextActions';
|
import useChatContextActions from '../../../hooks/useChatContextActions';
|
||||||
import useFlag from '../../../hooks/useFlag';
|
import useFlag from '../../../hooks/useFlag';
|
||||||
@ -83,11 +81,9 @@ type StateProps = {
|
|||||||
lastSyncTime?: number;
|
lastSyncTime?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'openChat' | 'focusLastMessage'>;
|
|
||||||
|
|
||||||
const ANIMATION_DURATION = 200;
|
const ANIMATION_DURATION = 200;
|
||||||
|
|
||||||
const Chat: FC<OwnProps & StateProps & DispatchProps> = ({
|
const Chat: FC<OwnProps & StateProps> = ({
|
||||||
style,
|
style,
|
||||||
chatId,
|
chatId,
|
||||||
folderId,
|
folderId,
|
||||||
@ -110,9 +106,12 @@ const Chat: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
canScrollDown,
|
canScrollDown,
|
||||||
canChangeFolder,
|
canChangeFolder,
|
||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
openChat,
|
|
||||||
focusLastMessage,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
openChat,
|
||||||
|
focusLastMessage,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
@ -390,8 +389,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
...(actionTargetUserIds && { usersById }),
|
...(actionTargetUserIds && { usersById }),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'openChat',
|
|
||||||
'focusLastMessage',
|
|
||||||
]),
|
|
||||||
)(Chat));
|
)(Chat));
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useMemo, useRef,
|
FC, memo, useCallback, useEffect, useMemo, useRef,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ApiChat, ApiChatFolder, ApiUser } from '../../../api/types';
|
||||||
import { GlobalActions, GlobalState } from '../../../global/types';
|
import { GlobalState } from '../../../global/types';
|
||||||
import { NotifyException, NotifySettings, SettingsScreens } from '../../../types';
|
import { NotifyException, NotifySettings, SettingsScreens } from '../../../types';
|
||||||
import { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer';
|
import { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer';
|
||||||
|
|
||||||
import { IS_TOUCH_ENV } from '../../../util/environment';
|
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 { captureEvents, SwipeDirection } from '../../../util/captureEvents';
|
||||||
import { getFolderUnreadDialogs } from '../../../modules/helpers';
|
import { getFolderUnreadDialogs } from '../../../modules/helpers';
|
||||||
import { selectNotifyExceptions, selectNotifySettings } from '../../../modules/selectors';
|
import { selectNotifyExceptions, selectNotifySettings } from '../../../modules/selectors';
|
||||||
@ -43,12 +43,10 @@ type StateProps = {
|
|||||||
shouldSkipHistoryAnimations?: boolean;
|
shouldSkipHistoryAnimations?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadChatFolders' | 'setActiveChatFolder' | 'openChat'>;
|
|
||||||
|
|
||||||
const INFO_THROTTLE = 3000;
|
const INFO_THROTTLE = 3000;
|
||||||
const SAVED_MESSAGES_HOTKEY = '0';
|
const SAVED_MESSAGES_HOTKEY = '0';
|
||||||
|
|
||||||
const ChatFolders: FC<OwnProps & StateProps & DispatchProps> = ({
|
const ChatFolders: FC<OwnProps & StateProps> = ({
|
||||||
allListIds,
|
allListIds,
|
||||||
chatsById,
|
chatsById,
|
||||||
usersById,
|
usersById,
|
||||||
@ -62,10 +60,13 @@ const ChatFolders: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
shouldSkipHistoryAnimations,
|
shouldSkipHistoryAnimations,
|
||||||
foldersDispatch,
|
foldersDispatch,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
loadChatFolders,
|
|
||||||
setActiveChatFolder,
|
|
||||||
openChat,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadChatFolders,
|
||||||
|
setActiveChatFolder,
|
||||||
|
openChat,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const transitionRef = useRef<HTMLDivElement>(null);
|
const transitionRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
@ -267,9 +268,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
shouldSkipHistoryAnimations,
|
shouldSkipHistoryAnimations,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'loadChatFolders',
|
|
||||||
'setActiveChatFolder',
|
|
||||||
'openChat',
|
|
||||||
]),
|
|
||||||
)(ChatFolders));
|
)(ChatFolders));
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useMemo, useCallback, useEffect,
|
FC, memo, useMemo, useCallback, useEffect,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 {
|
import {
|
||||||
ApiChat, ApiChatFolder, ApiUser,
|
ApiChat, ApiChatFolder, ApiUser,
|
||||||
} from '../../../api/types';
|
} 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 { ALL_CHATS_PRELOAD_DISABLED, CHAT_HEIGHT_PX, CHAT_LIST_SLICE } from '../../../config';
|
||||||
import { IS_ANDROID, IS_MAC_OS, IS_PWA } from '../../../util/environment';
|
import { IS_ANDROID, IS_MAC_OS, IS_PWA } from '../../../util/environment';
|
||||||
import usePrevious from '../../../hooks/usePrevious';
|
import usePrevious from '../../../hooks/usePrevious';
|
||||||
import { mapValues, pick } from '../../../util/iteratees';
|
import { mapValues } from '../../../util/iteratees';
|
||||||
import {
|
import {
|
||||||
getChatOrder, prepareChatList, prepareFolderListIds, reduceChatList,
|
getChatOrder, prepareChatList, prepareFolderListIds, reduceChatList,
|
||||||
} from '../../../modules/helpers';
|
} from '../../../modules/helpers';
|
||||||
@ -48,16 +48,12 @@ type StateProps = {
|
|||||||
notifyExceptions?: Record<number, NotifyException>;
|
notifyExceptions?: Record<number, NotifyException>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'loadMoreChats' | 'preloadTopChatMessages' | 'preloadArchivedChats' | 'openChat' | 'openNextChat'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
enum FolderTypeToListType {
|
enum FolderTypeToListType {
|
||||||
'all' = 'active',
|
'all' = 'active',
|
||||||
'archived' = 'archived',
|
'archived' = 'archived',
|
||||||
}
|
}
|
||||||
|
|
||||||
const ChatList: FC<OwnProps & StateProps & DispatchProps> = ({
|
const ChatList: FC<OwnProps & StateProps> = ({
|
||||||
folderType,
|
folderType,
|
||||||
folderId,
|
folderId,
|
||||||
isActive,
|
isActive,
|
||||||
@ -72,12 +68,15 @@ const ChatList: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
notifyExceptions,
|
notifyExceptions,
|
||||||
foldersDispatch,
|
foldersDispatch,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
loadMoreChats,
|
|
||||||
preloadTopChatMessages,
|
|
||||||
preloadArchivedChats,
|
|
||||||
openChat,
|
|
||||||
openNextChat,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadMoreChats,
|
||||||
|
preloadTopChatMessages,
|
||||||
|
preloadArchivedChats,
|
||||||
|
openChat,
|
||||||
|
openNextChat,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const [currentListIds, currentPinnedIds] = useMemo(() => {
|
const [currentListIds, currentPinnedIds] = useMemo(() => {
|
||||||
return folderType === 'folder' && chatFolder
|
return folderType === 'folder' && chatFolder
|
||||||
? prepareFolderListIds(allListIds, chatsById, usersById, chatFolder, notifySettings, notifyExceptions)
|
? 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));
|
)(ChatList));
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useEffect, useCallback, useMemo, memo,
|
FC, useEffect, useCallback, useMemo, memo,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ApiUser, ApiUserStatus } from '../../../api/types';
|
||||||
|
|
||||||
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import { throttle } from '../../../util/schedulers';
|
import { throttle } from '../../../util/schedulers';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import { filterUsersByName, sortUserIds } from '../../../modules/helpers';
|
import { filterUsersByName, sortUserIds } from '../../../modules/helpers';
|
||||||
import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
|
import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
|
||||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||||
@ -31,11 +29,9 @@ type StateProps = {
|
|||||||
serverTimeOffset: number;
|
serverTimeOffset: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadContactList' | 'openChat'>;
|
|
||||||
|
|
||||||
const runThrottled = throttle((cb) => cb(), 60000, true);
|
const runThrottled = throttle((cb) => cb(), 60000, true);
|
||||||
|
|
||||||
const ContactList: FC<OwnProps & StateProps & DispatchProps> = ({
|
const ContactList: FC<OwnProps & StateProps> = ({
|
||||||
isActive,
|
isActive,
|
||||||
filter,
|
filter,
|
||||||
usersById,
|
usersById,
|
||||||
@ -43,9 +39,12 @@ const ContactList: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
contactIds,
|
contactIds,
|
||||||
serverTimeOffset,
|
serverTimeOffset,
|
||||||
onReset,
|
onReset,
|
||||||
loadContactList,
|
|
||||||
openChat,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadContactList,
|
||||||
|
openChat,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
// Due to the parent Transition, this component never gets unmounted,
|
// Due to the parent Transition, this component never gets unmounted,
|
||||||
// that's why we use throttled API call on every update.
|
// that's why we use throttled API call on every update.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -108,5 +107,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
serverTimeOffset: global.serverTimeOffset,
|
serverTimeOffset: global.serverTimeOffset,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['loadContactList', 'openChat']),
|
|
||||||
)(ContactList));
|
)(ContactList));
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useCallback, useMemo, memo,
|
FC, useCallback, useMemo, memo,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { LeftColumnContent, ISettings } from '../../../types';
|
||||||
import { ApiChat } from '../../../api/types';
|
import { ApiChat } from '../../../api/types';
|
||||||
|
|
||||||
@ -12,7 +11,6 @@ import {
|
|||||||
} from '../../../config';
|
} from '../../../config';
|
||||||
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import { isChatArchived } from '../../../modules/helpers';
|
import { isChatArchived } from '../../../modules/helpers';
|
||||||
import { formatDateToString } from '../../../util/dateFormat';
|
import { formatDateToString } from '../../../util/dateFormat';
|
||||||
import { selectTheme } from '../../../modules/selectors';
|
import { selectTheme } from '../../../modules/selectors';
|
||||||
@ -51,10 +49,6 @@ type StateProps = {
|
|||||||
chatsById?: Record<string, ApiChat>;
|
chatsById?: Record<string, ApiChat>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'openChat' | 'openTipsChat' | 'setGlobalSearchDate' | 'setGlobalSearchChatId' | 'setSettingOption'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const ANIMATION_LEVEL_OPTIONS = [0, 1, 2];
|
const ANIMATION_LEVEL_OPTIONS = [0, 1, 2];
|
||||||
|
|
||||||
const PRODUCTION_HOSTNAME = 'web.telegram.org';
|
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 WEBK_VERSION_URL = 'https://web.telegram.org/k/';
|
||||||
const PERMANENT_VERSION_KEY = 'kz_version';
|
const PERMANENT_VERSION_KEY = 'kz_version';
|
||||||
|
|
||||||
const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
const LeftMainHeader: FC<OwnProps & StateProps> = ({
|
||||||
content,
|
content,
|
||||||
contactsFilter,
|
contactsFilter,
|
||||||
onSearchQuery,
|
onSearchQuery,
|
||||||
onSelectSettings,
|
onSelectSettings,
|
||||||
onSelectContacts,
|
onSelectContacts,
|
||||||
onSelectArchived,
|
onSelectArchived,
|
||||||
setGlobalSearchChatId,
|
|
||||||
onReset,
|
onReset,
|
||||||
searchQuery,
|
searchQuery,
|
||||||
isLoading,
|
isLoading,
|
||||||
@ -80,11 +73,14 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
theme,
|
theme,
|
||||||
animationLevel,
|
animationLevel,
|
||||||
chatsById,
|
chatsById,
|
||||||
openChat,
|
|
||||||
openTipsChat,
|
|
||||||
setGlobalSearchDate,
|
|
||||||
setSettingOption,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
openChat,
|
||||||
|
openTipsChat,
|
||||||
|
setGlobalSearchDate,
|
||||||
|
setSettingOption, setGlobalSearchChatId,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const hasMenu = content === LeftColumnContent.ChatList;
|
const hasMenu = content === LeftColumnContent.ChatList;
|
||||||
const clearedDateSearchParam = { date: undefined };
|
const clearedDateSearchParam = { date: undefined };
|
||||||
@ -327,11 +323,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
animationLevel,
|
animationLevel,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'openChat',
|
|
||||||
'openTipsChat',
|
|
||||||
'setGlobalSearchDate',
|
|
||||||
'setGlobalSearchChatId',
|
|
||||||
'setSettingOption',
|
|
||||||
]),
|
|
||||||
)(LeftMainHeader));
|
)(LeftMainHeader));
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useCallback, useEffect, useMemo, memo,
|
FC, useCallback, useEffect, useMemo, memo,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ApiChat } from '../../../api/types';
|
||||||
|
|
||||||
import { pick, unique } from '../../../util/iteratees';
|
import { unique } from '../../../util/iteratees';
|
||||||
import { throttle } from '../../../util/schedulers';
|
import { throttle } from '../../../util/schedulers';
|
||||||
import { filterUsersByName, isUserBot, sortChatIds } from '../../../modules/helpers';
|
import { filterUsersByName, isUserBot, sortChatIds } from '../../../modules/helpers';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
@ -34,11 +33,9 @@ type StateProps = {
|
|||||||
globalUserIds?: string[];
|
globalUserIds?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadContactList' | 'setGlobalSearchQuery'>;
|
|
||||||
|
|
||||||
const runThrottled = throttle((cb) => cb(), 60000, true);
|
const runThrottled = throttle((cb) => cb(), 60000, true);
|
||||||
|
|
||||||
const NewChatStep1: FC<OwnProps & StateProps & DispatchProps> = ({
|
const NewChatStep1: FC<OwnProps & StateProps> = ({
|
||||||
isChannel,
|
isChannel,
|
||||||
isActive,
|
isActive,
|
||||||
selectedMemberIds,
|
selectedMemberIds,
|
||||||
@ -51,9 +48,12 @@ const NewChatStep1: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
isSearching,
|
isSearching,
|
||||||
localUserIds,
|
localUserIds,
|
||||||
globalUserIds,
|
globalUserIds,
|
||||||
loadContactList,
|
|
||||||
setGlobalSearchQuery,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadContactList,
|
||||||
|
setGlobalSearchQuery,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
// Due to the parent Transition, this component never gets unmounted,
|
// Due to the parent Transition, this component never gets unmounted,
|
||||||
// that's why we use throttled API call on every update.
|
// that's why we use throttled API call on every update.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -162,5 +162,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
localUserIds,
|
localUserIds,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['loadContactList', 'setGlobalSearchQuery']),
|
|
||||||
)(NewChatStep1));
|
)(NewChatStep1));
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useState, useCallback, useEffect, memo,
|
FC, useState, useCallback, useEffect, memo,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ChatCreationProgress } from '../../../types';
|
||||||
|
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||||
|
|
||||||
@ -30,21 +28,22 @@ type StateProps = {
|
|||||||
creationError?: string;
|
creationError?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'createGroupChat' | 'createChannel'>;
|
|
||||||
|
|
||||||
// TODO @implement
|
// TODO @implement
|
||||||
const MAX_USERS_FOR_LEGACY_CHAT = 199; // Accounting for current user
|
const MAX_USERS_FOR_LEGACY_CHAT = 199; // Accounting for current user
|
||||||
|
|
||||||
const NewChatStep2: FC<OwnProps & StateProps & DispatchProps> = ({
|
const NewChatStep2: FC<OwnProps & StateProps > = ({
|
||||||
isChannel,
|
isChannel,
|
||||||
isActive,
|
isActive,
|
||||||
memberIds,
|
memberIds,
|
||||||
onReset,
|
onReset,
|
||||||
creationProgress,
|
creationProgress,
|
||||||
creationError,
|
creationError,
|
||||||
createGroupChat,
|
|
||||||
createChannel,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
createGroupChat,
|
||||||
|
createChannel,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
useHistoryBack(isActive, onReset);
|
useHistoryBack(isActive, onReset);
|
||||||
@ -202,7 +201,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
creationError,
|
creationError,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'createGroupChat', 'createChannel',
|
|
||||||
]),
|
|
||||||
)(NewChatStep2));
|
)(NewChatStep2));
|
||||||
|
|||||||
@ -1,15 +1,13 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useMemo,
|
FC, memo, useCallback, useMemo,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { AudioOrigin, LoadMoreDirection } from '../../../types';
|
||||||
|
|
||||||
import { SLIDE_TRANSITION_DURATION } from '../../../config';
|
import { SLIDE_TRANSITION_DURATION } from '../../../config';
|
||||||
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
||||||
import { createMapStateToProps, StateProps } from './helpers/createMapStateToProps';
|
import { createMapStateToProps, StateProps } from './helpers/createMapStateToProps';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import { formatMonthAndYear, toYearMonth } from '../../../util/dateFormat';
|
import { formatMonthAndYear, toYearMonth } from '../../../util/dateFormat';
|
||||||
import { getSenderName } from './helpers/getSenderName';
|
import { getSenderName } from './helpers/getSenderName';
|
||||||
import { throttle } from '../../../util/schedulers';
|
import { throttle } from '../../../util/schedulers';
|
||||||
@ -26,11 +24,9 @@ export type OwnProps = {
|
|||||||
searchQuery?: string;
|
searchQuery?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, ('searchMessagesGlobal' | 'focusMessage' | 'openAudioPlayer')>;
|
|
||||||
|
|
||||||
const runThrottled = throttle((cb) => cb(), 500, true);
|
const runThrottled = throttle((cb) => cb(), 500, true);
|
||||||
|
|
||||||
const AudioResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
const AudioResults: FC<OwnProps & StateProps> = ({
|
||||||
theme,
|
theme,
|
||||||
isVoice,
|
isVoice,
|
||||||
searchQuery,
|
searchQuery,
|
||||||
@ -42,10 +38,13 @@ const AudioResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
foundIds,
|
foundIds,
|
||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
activeDownloads,
|
activeDownloads,
|
||||||
searchMessagesGlobal,
|
|
||||||
focusMessage,
|
|
||||||
openAudioPlayer,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
searchMessagesGlobal,
|
||||||
|
focusMessage,
|
||||||
|
openAudioPlayer,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const currentType = isVoice ? 'voice' : 'audio';
|
const currentType = isVoice ? 'voice' : 'audio';
|
||||||
const handleLoadMore = useCallback(({ direction }: { direction: LoadMoreDirection }) => {
|
const handleLoadMore = useCallback(({ direction }: { direction: LoadMoreDirection }) => {
|
||||||
@ -137,9 +136,4 @@ const AudioResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
|
|
||||||
export default memo(withGlobal<OwnProps>(
|
export default memo(withGlobal<OwnProps>(
|
||||||
createMapStateToProps('audio'),
|
createMapStateToProps('audio'),
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'searchMessagesGlobal',
|
|
||||||
'focusMessage',
|
|
||||||
'openAudioPlayer',
|
|
||||||
]),
|
|
||||||
)(AudioResults));
|
)(AudioResults));
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback,
|
FC, memo, useCallback,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../../lib/teact/teactn';
|
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
|
||||||
|
|
||||||
import { GlobalActions } from '../../../global/types';
|
|
||||||
import {
|
import {
|
||||||
ApiChat, ApiUser, ApiMessage, ApiMessageOutgoingStatus,
|
ApiChat, ApiUser, ApiMessage, ApiMessageOutgoingStatus,
|
||||||
} from '../../../api/types';
|
} from '../../../api/types';
|
||||||
@ -20,7 +19,6 @@ import {
|
|||||||
} from '../../../modules/helpers';
|
} from '../../../modules/helpers';
|
||||||
import { selectChat, selectUser } from '../../../modules/selectors';
|
import { selectChat, selectUser } from '../../../modules/selectors';
|
||||||
import renderText from '../../common/helpers/renderText';
|
import renderText from '../../common/helpers/renderText';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import useMedia from '../../../hooks/useMedia';
|
import useMedia from '../../../hooks/useMedia';
|
||||||
import { formatPastTimeShort } from '../../../util/dateFormat';
|
import { formatPastTimeShort } from '../../../util/dateFormat';
|
||||||
import useLang, { LangFn } from '../../../hooks/useLang';
|
import useLang, { LangFn } from '../../../hooks/useLang';
|
||||||
@ -46,17 +44,16 @@ type StateProps = {
|
|||||||
lastSyncTime?: number;
|
lastSyncTime?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'focusMessage'>;
|
const ChatMessage: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const ChatMessage: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
message,
|
message,
|
||||||
searchQuery,
|
searchQuery,
|
||||||
chatId,
|
chatId,
|
||||||
chat,
|
chat,
|
||||||
privateChatUser,
|
privateChatUser,
|
||||||
focusMessage,
|
|
||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { focusMessage } = getDispatch();
|
||||||
|
|
||||||
const mediaThumbnail = getMessageMediaThumbDataUri(message);
|
const mediaThumbnail = getMessageMediaThumbDataUri(message);
|
||||||
const mediaBlobUrl = useMedia(getMessageMediaHash(message, 'micro'));
|
const mediaBlobUrl = useMedia(getMessageMediaHash(message, 'micro'));
|
||||||
const isRoundVideo = Boolean(getMessageRoundVideo(message));
|
const isRoundVideo = Boolean(getMessageRoundVideo(message));
|
||||||
@ -140,7 +137,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
...(privateChatUserId && { privateChatUser: selectUser(global, privateChatUserId) }),
|
...(privateChatUserId && { privateChatUser: selectUser(global, privateChatUserId) }),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'focusMessage',
|
|
||||||
]),
|
|
||||||
)(ChatMessage));
|
)(ChatMessage));
|
||||||
|
|||||||
@ -1,13 +1,11 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useMemo,
|
FC, memo, useCallback, useMemo,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../../lib/teact/teactn';
|
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
|
||||||
|
|
||||||
import { ApiChat, ApiMessage } from '../../../api/types';
|
import { ApiChat, ApiMessage } from '../../../api/types';
|
||||||
import { GlobalActions } from '../../../global/types';
|
|
||||||
import { LoadMoreDirection } from '../../../types';
|
import { LoadMoreDirection } from '../../../types';
|
||||||
|
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import { getMessageSummaryText } from '../../../modules/helpers';
|
import { getMessageSummaryText } from '../../../modules/helpers';
|
||||||
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
||||||
import { throttle } from '../../../util/schedulers';
|
import { throttle } from '../../../util/schedulers';
|
||||||
@ -34,11 +32,9 @@ type StateProps = {
|
|||||||
lastSyncTime?: number;
|
lastSyncTime?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, ('searchMessagesGlobal')>;
|
|
||||||
|
|
||||||
const runThrottled = throttle((cb) => cb(), 500, true);
|
const runThrottled = throttle((cb) => cb(), 500, true);
|
||||||
|
|
||||||
const ChatMessageResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
const ChatMessageResults: FC<OwnProps & StateProps> = ({
|
||||||
searchQuery,
|
searchQuery,
|
||||||
currentUserId,
|
currentUserId,
|
||||||
dateSearchQuery,
|
dateSearchQuery,
|
||||||
@ -47,9 +43,10 @@ const ChatMessageResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
chatsById,
|
chatsById,
|
||||||
fetchingStatus,
|
fetchingStatus,
|
||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
searchMessagesGlobal,
|
|
||||||
onSearchDateSelect,
|
onSearchDateSelect,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { searchMessagesGlobal } = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const handleLoadMore = useCallback(({ direction }: { direction: LoadMoreDirection }) => {
|
const handleLoadMore = useCallback(({ direction }: { direction: LoadMoreDirection }) => {
|
||||||
if (lastSyncTime && direction === LoadMoreDirection.Backwards) {
|
if (lastSyncTime && direction === LoadMoreDirection.Backwards) {
|
||||||
@ -142,5 +139,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['searchMessagesGlobal']),
|
|
||||||
)(ChatMessageResults));
|
)(ChatMessageResults));
|
||||||
|
|||||||
@ -1,14 +1,13 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useMemo, useState,
|
FC, memo, useCallback, useMemo, useState,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ApiChat, ApiMessage } from '../../../api/types';
|
||||||
import { GlobalActions } from '../../../global/types';
|
|
||||||
import { LoadMoreDirection } from '../../../types';
|
import { LoadMoreDirection } from '../../../types';
|
||||||
|
|
||||||
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
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 { getMessageSummaryText, sortChatIds, filterUsersByName } from '../../../modules/helpers';
|
||||||
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
||||||
import { throttle } from '../../../util/schedulers';
|
import { throttle } from '../../../util/schedulers';
|
||||||
@ -45,21 +44,21 @@ type StateProps = {
|
|||||||
lastSyncTime?: number;
|
lastSyncTime?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'openChat' | 'addRecentlyFoundChatId' | 'searchMessagesGlobal' | 'setGlobalSearchChatId'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const MIN_QUERY_LENGTH_FOR_GLOBAL_SEARCH = 4;
|
const MIN_QUERY_LENGTH_FOR_GLOBAL_SEARCH = 4;
|
||||||
const LESS_LIST_ITEMS_AMOUNT = 5;
|
const LESS_LIST_ITEMS_AMOUNT = 5;
|
||||||
|
|
||||||
const runThrottled = throttle((cb) => cb(), 500, true);
|
const runThrottled = throttle((cb) => cb(), 500, true);
|
||||||
|
|
||||||
const ChatResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
const ChatResults: FC<OwnProps & StateProps> = ({
|
||||||
searchQuery, searchDate, dateSearchQuery, currentUserId,
|
searchQuery, searchDate, dateSearchQuery, currentUserId,
|
||||||
localContactIds, localChatIds, localUserIds, globalChatIds, globalUserIds,
|
localContactIds, localChatIds, localUserIds, globalChatIds, globalUserIds,
|
||||||
foundIds, globalMessagesByChatId, chatsById, fetchingStatus, lastSyncTime,
|
foundIds, globalMessagesByChatId, chatsById, fetchingStatus, lastSyncTime,
|
||||||
onReset, onSearchDateSelect, openChat, addRecentlyFoundChatId, searchMessagesGlobal, setGlobalSearchChatId,
|
onReset, onSearchDateSelect,
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
openChat, addRecentlyFoundChatId, searchMessagesGlobal, setGlobalSearchChatId,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const [shouldShowMoreLocal, setShouldShowMoreLocal] = useState<boolean>(false);
|
const [shouldShowMoreLocal, setShouldShowMoreLocal] = useState<boolean>(false);
|
||||||
@ -306,10 +305,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'openChat',
|
|
||||||
'addRecentlyFoundChatId',
|
|
||||||
'searchMessagesGlobal',
|
|
||||||
'setGlobalSearchChatId',
|
|
||||||
]),
|
|
||||||
)(ChatResults));
|
)(ChatResults));
|
||||||
|
|||||||
@ -1,16 +1,14 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useMemo,
|
FC, memo, useCallback, useMemo,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../../lib/teact/teactn';
|
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
|
||||||
|
|
||||||
import { ApiMessage } from '../../../api/types';
|
import { ApiMessage } from '../../../api/types';
|
||||||
import { GlobalActions } from '../../../global/types';
|
|
||||||
import { LoadMoreDirection } from '../../../types';
|
import { LoadMoreDirection } from '../../../types';
|
||||||
|
|
||||||
import { SLIDE_TRANSITION_DURATION } from '../../../config';
|
import { SLIDE_TRANSITION_DURATION } from '../../../config';
|
||||||
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
||||||
import { createMapStateToProps, StateProps } from './helpers/createMapStateToProps';
|
import { createMapStateToProps, StateProps } from './helpers/createMapStateToProps';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import { formatMonthAndYear, toYearMonth } from '../../../util/dateFormat';
|
import { formatMonthAndYear, toYearMonth } from '../../../util/dateFormat';
|
||||||
import { getSenderName } from './helpers/getSenderName';
|
import { getSenderName } from './helpers/getSenderName';
|
||||||
import { throttle } from '../../../util/schedulers';
|
import { throttle } from '../../../util/schedulers';
|
||||||
@ -27,12 +25,10 @@ export type OwnProps = {
|
|||||||
searchQuery?: string;
|
searchQuery?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, ('searchMessagesGlobal' | 'focusMessage')>;
|
|
||||||
|
|
||||||
const CURRENT_TYPE = 'documents';
|
const CURRENT_TYPE = 'documents';
|
||||||
const runThrottled = throttle((cb) => cb(), 500, true);
|
const runThrottled = throttle((cb) => cb(), 500, true);
|
||||||
|
|
||||||
const FileResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
const FileResults: FC<OwnProps & StateProps> = ({
|
||||||
searchQuery,
|
searchQuery,
|
||||||
searchChatId,
|
searchChatId,
|
||||||
isLoading,
|
isLoading,
|
||||||
@ -42,9 +38,12 @@ const FileResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
foundIds,
|
foundIds,
|
||||||
activeDownloads,
|
activeDownloads,
|
||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
searchMessagesGlobal,
|
|
||||||
focusMessage,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
searchMessagesGlobal,
|
||||||
|
focusMessage,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const handleLoadMore = useCallback(({ direction }: { direction: LoadMoreDirection }) => {
|
const handleLoadMore = useCallback(({ direction }: { direction: LoadMoreDirection }) => {
|
||||||
if (lastSyncTime && direction === LoadMoreDirection.Backwards) {
|
if (lastSyncTime && direction === LoadMoreDirection.Backwards) {
|
||||||
@ -127,8 +126,4 @@ const FileResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
|
|
||||||
export default memo(withGlobal<OwnProps>(
|
export default memo(withGlobal<OwnProps>(
|
||||||
createMapStateToProps(CURRENT_TYPE),
|
createMapStateToProps(CURRENT_TYPE),
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'searchMessagesGlobal',
|
|
||||||
'focusMessage',
|
|
||||||
]),
|
|
||||||
)(FileResults));
|
)(FileResults));
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useState, useMemo, useRef,
|
FC, memo, useCallback, useState, useMemo, useRef,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { GlobalSearchContent } from '../../../types';
|
||||||
|
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import { parseDateString } from '../../../util/dateFormat';
|
import { parseDateString } from '../../../util/dateFormat';
|
||||||
import useKeyboardListNavigation from '../../../hooks/useKeyboardListNavigation';
|
import useKeyboardListNavigation from '../../../hooks/useKeyboardListNavigation';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
@ -35,8 +33,6 @@ type StateProps = {
|
|||||||
chatId?: string;
|
chatId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, ('setGlobalSearchContent' | 'setGlobalSearchDate')>;
|
|
||||||
|
|
||||||
const TABS = [
|
const TABS = [
|
||||||
{ type: GlobalSearchContent.ChatList, title: 'SearchAllChatsShort' },
|
{ type: GlobalSearchContent.ChatList, title: 'SearchAllChatsShort' },
|
||||||
{ type: GlobalSearchContent.Media, title: 'SharedMediaTab2' },
|
{ type: GlobalSearchContent.Media, title: 'SharedMediaTab2' },
|
||||||
@ -53,16 +49,19 @@ const CHAT_TABS = [
|
|||||||
|
|
||||||
const TRANSITION_RENDER_COUNT = Object.keys(GlobalSearchContent).length / 2;
|
const TRANSITION_RENDER_COUNT = Object.keys(GlobalSearchContent).length / 2;
|
||||||
|
|
||||||
const LeftSearch: FC<OwnProps & StateProps & DispatchProps> = ({
|
const LeftSearch: FC<OwnProps & StateProps> = ({
|
||||||
searchQuery,
|
searchQuery,
|
||||||
searchDate,
|
searchDate,
|
||||||
isActive,
|
isActive,
|
||||||
currentContent = GlobalSearchContent.ChatList,
|
currentContent = GlobalSearchContent.ChatList,
|
||||||
chatId,
|
chatId,
|
||||||
setGlobalSearchContent,
|
|
||||||
setGlobalSearchDate,
|
|
||||||
onReset,
|
onReset,
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
setGlobalSearchContent,
|
||||||
|
setGlobalSearchDate,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const [activeTab, setActiveTab] = useState(currentContent);
|
const [activeTab, setActiveTab] = useState(currentContent);
|
||||||
const dateSearchQuery = useMemo(() => parseDateString(searchQuery), [searchQuery]);
|
const dateSearchQuery = useMemo(() => parseDateString(searchQuery), [searchQuery]);
|
||||||
@ -149,5 +148,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
|
|
||||||
return { currentContent, chatId };
|
return { currentContent, chatId };
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['setGlobalSearchContent', 'setGlobalSearchDate']),
|
|
||||||
)(LeftSearch));
|
)(LeftSearch));
|
||||||
|
|||||||
@ -1,15 +1,13 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useMemo,
|
FC, memo, useCallback, useMemo,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { LoadMoreDirection } from '../../../types';
|
||||||
|
|
||||||
import { SLIDE_TRANSITION_DURATION } from '../../../config';
|
import { SLIDE_TRANSITION_DURATION } from '../../../config';
|
||||||
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
||||||
import { createMapStateToProps, StateProps } from './helpers/createMapStateToProps';
|
import { createMapStateToProps, StateProps } from './helpers/createMapStateToProps';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import { formatMonthAndYear, toYearMonth } from '../../../util/dateFormat';
|
import { formatMonthAndYear, toYearMonth } from '../../../util/dateFormat';
|
||||||
import { getSenderName } from './helpers/getSenderName';
|
import { getSenderName } from './helpers/getSenderName';
|
||||||
import { throttle } from '../../../util/schedulers';
|
import { throttle } from '../../../util/schedulers';
|
||||||
@ -25,12 +23,10 @@ export type OwnProps = {
|
|||||||
searchQuery?: string;
|
searchQuery?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, ('searchMessagesGlobal' | 'focusMessage')>;
|
|
||||||
|
|
||||||
const CURRENT_TYPE = 'links';
|
const CURRENT_TYPE = 'links';
|
||||||
const runThrottled = throttle((cb) => cb(), 500, true);
|
const runThrottled = throttle((cb) => cb(), 500, true);
|
||||||
|
|
||||||
const LinkResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
const LinkResults: FC<OwnProps & StateProps> = ({
|
||||||
searchQuery,
|
searchQuery,
|
||||||
searchChatId,
|
searchChatId,
|
||||||
isLoading,
|
isLoading,
|
||||||
@ -39,9 +35,12 @@ const LinkResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
globalMessagesByChatId,
|
globalMessagesByChatId,
|
||||||
foundIds,
|
foundIds,
|
||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
searchMessagesGlobal,
|
|
||||||
focusMessage,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
searchMessagesGlobal,
|
||||||
|
focusMessage,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const handleLoadMore = useCallback(({ direction }: { direction: LoadMoreDirection }) => {
|
const handleLoadMore = useCallback(({ direction }: { direction: LoadMoreDirection }) => {
|
||||||
if (lastSyncTime && direction === LoadMoreDirection.Backwards) {
|
if (lastSyncTime && direction === LoadMoreDirection.Backwards) {
|
||||||
@ -122,8 +121,4 @@ const LinkResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
|
|
||||||
export default memo(withGlobal<OwnProps>(
|
export default memo(withGlobal<OwnProps>(
|
||||||
createMapStateToProps(CURRENT_TYPE),
|
createMapStateToProps(CURRENT_TYPE),
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'searchMessagesGlobal',
|
|
||||||
'focusMessage',
|
|
||||||
]),
|
|
||||||
)(LinkResults));
|
)(LinkResults));
|
||||||
|
|||||||
@ -1,15 +1,13 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useMemo,
|
FC, memo, useCallback, useMemo,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { LoadMoreDirection, MediaViewerOrigin } from '../../../types';
|
||||||
|
|
||||||
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
||||||
import { SLIDE_TRANSITION_DURATION } from '../../../config';
|
import { SLIDE_TRANSITION_DURATION } from '../../../config';
|
||||||
import { createMapStateToProps, StateProps } from './helpers/createMapStateToProps';
|
import { createMapStateToProps, StateProps } from './helpers/createMapStateToProps';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import { throttle } from '../../../util/schedulers';
|
import { throttle } from '../../../util/schedulers';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
@ -25,21 +23,22 @@ export type OwnProps = {
|
|||||||
searchQuery?: string;
|
searchQuery?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, ('searchMessagesGlobal' | 'openMediaViewer')>;
|
|
||||||
|
|
||||||
const CURRENT_TYPE = 'media';
|
const CURRENT_TYPE = 'media';
|
||||||
const runThrottled = throttle((cb) => cb(), 500, true);
|
const runThrottled = throttle((cb) => cb(), 500, true);
|
||||||
|
|
||||||
const MediaResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
const MediaResults: FC<OwnProps & StateProps> = ({
|
||||||
searchQuery,
|
searchQuery,
|
||||||
searchChatId,
|
searchChatId,
|
||||||
isLoading,
|
isLoading,
|
||||||
globalMessagesByChatId,
|
globalMessagesByChatId,
|
||||||
foundIds,
|
foundIds,
|
||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
searchMessagesGlobal,
|
|
||||||
openMediaViewer,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
searchMessagesGlobal,
|
||||||
|
openMediaViewer,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const handleLoadMore = useCallback(({ direction }: { direction: LoadMoreDirection }) => {
|
const handleLoadMore = useCallback(({ direction }: { direction: LoadMoreDirection }) => {
|
||||||
@ -133,8 +132,4 @@ const MediaResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
|
|
||||||
export default memo(withGlobal<OwnProps>(
|
export default memo(withGlobal<OwnProps>(
|
||||||
createMapStateToProps(CURRENT_TYPE),
|
createMapStateToProps(CURRENT_TYPE),
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'searchMessagesGlobal',
|
|
||||||
'openMediaViewer',
|
|
||||||
]),
|
|
||||||
)(MediaResults));
|
)(MediaResults));
|
||||||
|
|||||||
@ -1,15 +1,13 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useEffect, useCallback, useRef, memo,
|
FC, useEffect, useCallback, useRef, memo,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ApiUser } from '../../../api/types';
|
||||||
|
|
||||||
import { getUserFirstOrLastName } from '../../../modules/helpers';
|
import { getUserFirstOrLastName } from '../../../modules/helpers';
|
||||||
import renderText from '../../common/helpers/renderText';
|
import renderText from '../../common/helpers/renderText';
|
||||||
import { throttle } from '../../../util/schedulers';
|
import { throttle } from '../../../util/schedulers';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import useHorizontalScroll from '../../../hooks/useHorizontalScroll';
|
import useHorizontalScroll from '../../../hooks/useHorizontalScroll';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
|
|
||||||
@ -29,20 +27,20 @@ type StateProps = {
|
|||||||
recentlyFoundChatIds?: string[];
|
recentlyFoundChatIds?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'loadTopUsers' | 'loadContactList' | 'openChat' | 'addRecentlyFoundChatId' | 'clearRecentlyFoundChats'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const SEARCH_CLOSE_TIMEOUT_MS = 250;
|
const SEARCH_CLOSE_TIMEOUT_MS = 250;
|
||||||
const NBSP = '\u00A0';
|
const NBSP = '\u00A0';
|
||||||
|
|
||||||
const runThrottled = throttle((cb) => cb(), 60000, true);
|
const runThrottled = throttle((cb) => cb(), 60000, true);
|
||||||
|
|
||||||
const RecentContacts: FC<OwnProps & StateProps & DispatchProps> = ({
|
const RecentContacts: FC<OwnProps & StateProps> = ({
|
||||||
topUserIds, usersById, recentlyFoundChatIds,
|
topUserIds, usersById, recentlyFoundChatIds,
|
||||||
onReset, loadTopUsers, loadContactList, openChat,
|
onReset,
|
||||||
addRecentlyFoundChatId, clearRecentlyFoundChats,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadTopUsers, loadContactList, openChat,
|
||||||
|
addRecentlyFoundChatId, clearRecentlyFoundChats,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const topUsersRef = useRef<HTMLDivElement>(null);
|
const topUsersRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
@ -122,11 +120,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
recentlyFoundChatIds,
|
recentlyFoundChatIds,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'loadTopUsers',
|
|
||||||
'loadContactList',
|
|
||||||
'openChat',
|
|
||||||
'addRecentlyFoundChatId',
|
|
||||||
'clearRecentlyFoundChats',
|
|
||||||
]),
|
|
||||||
)(RecentContacts));
|
)(RecentContacts));
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useMemo, useState, memo, useRef, useCallback, useEffect,
|
FC, useMemo, useState, memo, useRef, useCallback, useEffect,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ApiUser } from '../../../api/types';
|
||||||
|
|
||||||
import { filterUsersByName, getUserFullName } from '../../../modules/helpers';
|
import { filterUsersByName, getUserFullName } from '../../../modules/helpers';
|
||||||
import { pick, unique } from '../../../util/iteratees';
|
import { unique } from '../../../util/iteratees';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
|
|
||||||
import ChatOrUserPicker from '../../common/ChatOrUserPicker';
|
import ChatOrUserPicker from '../../common/ChatOrUserPicker';
|
||||||
@ -25,9 +24,7 @@ type StateProps = {
|
|||||||
currentUserId?: string;
|
currentUserId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadContactList' | 'setUserSearchQuery' | 'blockContact'>;
|
const BlockUserModal: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const BlockUserModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
usersById,
|
usersById,
|
||||||
blockedIds,
|
blockedIds,
|
||||||
contactIds,
|
contactIds,
|
||||||
@ -35,10 +32,13 @@ const BlockUserModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
currentUserId,
|
currentUserId,
|
||||||
isOpen,
|
isOpen,
|
||||||
onClose,
|
onClose,
|
||||||
loadContactList,
|
|
||||||
setUserSearchQuery,
|
|
||||||
blockContact,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadContactList,
|
||||||
|
setUserSearchQuery,
|
||||||
|
blockContact,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const [filter, setFilter] = useState('');
|
const [filter, setFilter] = useState('');
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
@ -110,7 +110,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
currentUserId,
|
currentUserId,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'loadContactList', 'setUserSearchQuery', 'blockContact',
|
|
||||||
]),
|
|
||||||
)(BlockUserModal));
|
)(BlockUserModal));
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import React, { FC, memo, useCallback } from '../../../lib/teact/teact';
|
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 { SettingsScreens, ISettings } from '../../../types';
|
||||||
|
|
||||||
import { AUTODOWNLOAD_FILESIZE_MB_LIMITS } from '../../../config';
|
import { AUTODOWNLOAD_FILESIZE_MB_LIMITS } from '../../../config';
|
||||||
@ -36,11 +35,7 @@ type StateProps = Pick<ISettings, (
|
|||||||
'autoLoadFileMaxSizeMb'
|
'autoLoadFileMaxSizeMb'
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
const SettingsDataStorage: FC<OwnProps & StateProps> = ({
|
||||||
'setSettingOption'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const SettingsDataStorage: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
isActive,
|
isActive,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
onReset,
|
onReset,
|
||||||
@ -59,8 +54,9 @@ const SettingsDataStorage: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
canAutoPlayGifs,
|
canAutoPlayGifs,
|
||||||
canAutoPlayVideos,
|
canAutoPlayVideos,
|
||||||
autoLoadFileMaxSizeMb,
|
autoLoadFileMaxSizeMb,
|
||||||
setSettingOption,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { setSettingOption } = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
useHistoryBack(isActive, onReset, onScreenSelect, SettingsScreens.General);
|
useHistoryBack(isActive, onReset, onScreenSelect, SettingsScreens.General);
|
||||||
@ -193,7 +189,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
'autoLoadFileMaxSizeMb',
|
'autoLoadFileMaxSizeMb',
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'setSettingOption',
|
|
||||||
]),
|
|
||||||
)(SettingsDataStorage));
|
)(SettingsDataStorage));
|
||||||
|
|||||||
@ -2,14 +2,12 @@ import { ChangeEvent } from 'react';
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useState, useCallback, memo, useEffect, useMemo,
|
FC, useState, useCallback, memo, useEffect, useMemo,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../../lib/teact/teactn';
|
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
|
||||||
|
|
||||||
import { ApiMediaFormat } from '../../../api/types';
|
import { ApiMediaFormat } from '../../../api/types';
|
||||||
import { GlobalActions } from '../../../global/types';
|
|
||||||
import { ProfileEditProgress, SettingsScreens } from '../../../types';
|
import { ProfileEditProgress, SettingsScreens } from '../../../types';
|
||||||
|
|
||||||
import { throttle } from '../../../util/schedulers';
|
import { throttle } from '../../../util/schedulers';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import { selectUser } from '../../../modules/selectors';
|
import { selectUser } from '../../../modules/selectors';
|
||||||
import { getChatAvatarHash } from '../../../modules/helpers';
|
import { getChatAvatarHash } from '../../../modules/helpers';
|
||||||
import useMedia from '../../../hooks/useMedia';
|
import useMedia from '../../../hooks/useMedia';
|
||||||
@ -39,10 +37,6 @@ type StateProps = {
|
|||||||
isUsernameAvailable?: boolean;
|
isUsernameAvailable?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'loadCurrentUser' | 'updateProfile' | 'checkUsername'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const runThrottled = throttle((cb) => cb(), 60000, true);
|
const runThrottled = throttle((cb) => cb(), 60000, true);
|
||||||
|
|
||||||
const MAX_BIO_LENGTH = 70;
|
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_FIRST_NAME_MISSING = 'Please provide your first name';
|
||||||
const ERROR_BIO_TOO_LONG = 'Bio can\' be longer than 70 characters';
|
const ERROR_BIO_TOO_LONG = 'Bio can\' be longer than 70 characters';
|
||||||
|
|
||||||
const SettingsEditProfile: FC<OwnProps & StateProps & DispatchProps> = ({
|
const SettingsEditProfile: FC<OwnProps & StateProps> = ({
|
||||||
isActive,
|
isActive,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
onReset,
|
onReset,
|
||||||
@ -61,10 +55,13 @@ const SettingsEditProfile: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
currentUsername,
|
currentUsername,
|
||||||
progress,
|
progress,
|
||||||
isUsernameAvailable,
|
isUsernameAvailable,
|
||||||
loadCurrentUser,
|
|
||||||
updateProfile,
|
|
||||||
checkUsername,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadCurrentUser,
|
||||||
|
updateProfile,
|
||||||
|
checkUsername,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const [isUsernameTouched, setIsUsernameTouched] = useState(false);
|
const [isUsernameTouched, setIsUsernameTouched] = useState(false);
|
||||||
@ -286,9 +283,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
isUsernameAvailable,
|
isUsernameAvailable,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'loadCurrentUser',
|
|
||||||
'updateProfile',
|
|
||||||
'checkUsername',
|
|
||||||
]),
|
|
||||||
)(SettingsEditProfile));
|
)(SettingsEditProfile));
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useCallback, memo, useEffect, useRef, useState,
|
FC, useCallback, memo, useEffect, useRef, useState,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { SettingsScreens, ISettings, TimeFormat } from '../../../types';
|
||||||
import { ApiSticker, ApiStickerSet } from '../../../api/types';
|
import { ApiSticker, ApiStickerSet } from '../../../api/types';
|
||||||
|
|
||||||
@ -28,21 +27,18 @@ type OwnProps = {
|
|||||||
onReset: () => void;
|
onReset: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps = Pick<ISettings, (
|
type StateProps =
|
||||||
'messageTextSize' |
|
Pick<ISettings, (
|
||||||
'animationLevel' |
|
'messageTextSize' |
|
||||||
'messageSendKeyCombo' |
|
'animationLevel' |
|
||||||
'shouldSuggestStickers' |
|
'messageSendKeyCombo' |
|
||||||
'shouldLoopStickers' |
|
'shouldSuggestStickers' |
|
||||||
'timeFormat'
|
'shouldLoopStickers' |
|
||||||
)> & {
|
'timeFormat'
|
||||||
stickerSetIds?: string[];
|
)> & {
|
||||||
stickerSetsById?: Record<string, ApiStickerSet>;
|
stickerSetIds?: string[];
|
||||||
};
|
stickerSetsById?: Record<string, ApiStickerSet>;
|
||||||
|
};
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'setSettingOption' | 'loadStickerSets' | 'loadAddedStickers'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const ANIMATION_LEVEL_OPTIONS = [
|
const ANIMATION_LEVEL_OPTIONS = [
|
||||||
'Solid and Steady',
|
'Solid and Steady',
|
||||||
@ -58,7 +54,7 @@ const TIME_FORMAT_OPTIONS: IRadioOption[] = [{
|
|||||||
value: '24h',
|
value: '24h',
|
||||||
}];
|
}];
|
||||||
|
|
||||||
const SettingsGeneral: FC<OwnProps & StateProps & DispatchProps> = ({
|
const SettingsGeneral: FC<OwnProps & StateProps> = ({
|
||||||
isActive,
|
isActive,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
onReset,
|
onReset,
|
||||||
@ -70,10 +66,13 @@ const SettingsGeneral: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
shouldSuggestStickers,
|
shouldSuggestStickers,
|
||||||
shouldLoopStickers,
|
shouldLoopStickers,
|
||||||
timeFormat,
|
timeFormat,
|
||||||
setSettingOption,
|
|
||||||
loadStickerSets,
|
|
||||||
loadAddedStickers,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
setSettingOption,
|
||||||
|
loadStickerSets,
|
||||||
|
loadAddedStickers,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const stickerSettingsRef = useRef<HTMLDivElement>(null);
|
const stickerSettingsRef = useRef<HTMLDivElement>(null);
|
||||||
const { observe: observeIntersectionForCovers } = useIntersectionObserver({ rootRef: stickerSettingsRef });
|
const { observe: observeIntersectionForCovers } = useIntersectionObserver({ rootRef: stickerSettingsRef });
|
||||||
@ -252,7 +251,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
stickerSetsById: global.stickers.setsById,
|
stickerSetsById: global.stickers.setsById,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'setSettingOption', 'loadStickerSets', 'loadAddedStickers',
|
|
||||||
]),
|
|
||||||
)(SettingsGeneral));
|
)(SettingsGeneral));
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useEffect, useCallback, useRef,
|
FC, memo, useEffect, useCallback, useRef,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { SettingsScreens, ThemeKey, UPLOADING_WALLPAPER_SLUG } from '../../../types';
|
||||||
import { ApiWallpaper } from '../../../api/types';
|
import { ApiWallpaper } from '../../../api/types';
|
||||||
|
|
||||||
import { DARK_THEME_PATTERN_COLOR, DEFAULT_PATTERN_COLOR } from '../../../config';
|
import { DARK_THEME_PATTERN_COLOR, DEFAULT_PATTERN_COLOR } from '../../../config';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import { throttle } from '../../../util/schedulers';
|
import { throttle } from '../../../util/schedulers';
|
||||||
import { openSystemFilesDialog } from '../../../util/systemFilesDialog';
|
import { openSystemFilesDialog } from '../../../util/systemFilesDialog';
|
||||||
import { getAverageColor, getPatternColor, rgb2hex } from '../../../util/colors';
|
import { getAverageColor, getPatternColor, rgb2hex } from '../../../util/colors';
|
||||||
@ -36,15 +34,11 @@ type StateProps = {
|
|||||||
theme: ThemeKey;
|
theme: ThemeKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'loadWallpapers' | 'uploadWallpaper' | 'setThemeSettings'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const SUPPORTED_TYPES = 'image/jpeg';
|
const SUPPORTED_TYPES = 'image/jpeg';
|
||||||
|
|
||||||
const runThrottled = throttle((cb) => cb(), 60000, true);
|
const runThrottled = throttle((cb) => cb(), 60000, true);
|
||||||
|
|
||||||
const SettingsGeneralBackground: FC<OwnProps & StateProps & DispatchProps> = ({
|
const SettingsGeneralBackground: FC<OwnProps & StateProps> = ({
|
||||||
isActive,
|
isActive,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
onReset,
|
onReset,
|
||||||
@ -52,10 +46,13 @@ const SettingsGeneralBackground: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
isBlurred,
|
isBlurred,
|
||||||
loadedWallpapers,
|
loadedWallpapers,
|
||||||
theme,
|
theme,
|
||||||
loadWallpapers,
|
|
||||||
uploadWallpaper,
|
|
||||||
setThemeSettings,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadWallpapers,
|
||||||
|
uploadWallpaper,
|
||||||
|
setThemeSettings,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const themeRef = useRef<string>();
|
const themeRef = useRef<string>();
|
||||||
themeRef.current = theme;
|
themeRef.current = theme;
|
||||||
// Due to the parent Transition, this component never gets unmounted,
|
// Due to the parent Transition, this component never gets unmounted,
|
||||||
@ -177,7 +174,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
theme,
|
theme,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'loadWallpapers', 'uploadWallpaper', 'setThemeSettings',
|
|
||||||
]),
|
|
||||||
)(SettingsGeneralBackground));
|
)(SettingsGeneralBackground));
|
||||||
|
|||||||
@ -2,9 +2,8 @@ import { ChangeEvent, MutableRefObject, RefObject } from 'react';
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useRef, useState,
|
FC, memo, useCallback, useEffect, useRef, useState,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { SettingsScreens, ThemeKey } from '../../../types';
|
||||||
|
|
||||||
import { pick } from '../../../util/iteratees';
|
import { pick } from '../../../util/iteratees';
|
||||||
@ -32,8 +31,6 @@ type StateProps = {
|
|||||||
theme: ThemeKey;
|
theme: ThemeKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'setThemeSettings'>;
|
|
||||||
|
|
||||||
interface CanvasRects {
|
interface CanvasRects {
|
||||||
colorRect: {
|
colorRect: {
|
||||||
offsetLeft: number;
|
offsetLeft: number;
|
||||||
@ -53,14 +50,15 @@ const PREDEFINED_COLORS = [
|
|||||||
'#ccd0af', '#a6a997', '#7a7072', '#fdd7af', '#fdb76e', '#dd8851',
|
'#ccd0af', '#a6a997', '#7a7072', '#fdd7af', '#fdb76e', '#dd8851',
|
||||||
];
|
];
|
||||||
|
|
||||||
const SettingsGeneralBackground: FC<OwnProps & StateProps & DispatchProps> = ({
|
const SettingsGeneralBackground: FC<OwnProps & StateProps> = ({
|
||||||
isActive,
|
isActive,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
onReset,
|
onReset,
|
||||||
theme,
|
theme,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
setThemeSettings,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { setThemeSettings } = getDispatch();
|
||||||
|
|
||||||
const themeRef = useRef<string>();
|
const themeRef = useRef<string>();
|
||||||
themeRef.current = theme;
|
themeRef.current = theme;
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
@ -358,5 +356,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
theme,
|
theme,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['setThemeSettings']),
|
|
||||||
)(SettingsGeneralBackground));
|
)(SettingsGeneralBackground));
|
||||||
|
|||||||
@ -1,13 +1,11 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useMemo, useState,
|
FC, memo, useCallback, useMemo, useState,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { SettingsScreens } from '../../../types';
|
||||||
|
|
||||||
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
|
|
||||||
import DropdownMenu from '../../ui/DropdownMenu';
|
import DropdownMenu from '../../ui/DropdownMenu';
|
||||||
@ -23,17 +21,18 @@ type OwnProps = {
|
|||||||
onScreenSelect: (screen: SettingsScreens) => void;
|
onScreenSelect: (screen: SettingsScreens) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'signOut' | 'deleteChatFolder'>;
|
const SettingsHeader: FC<OwnProps> = ({
|
||||||
|
|
||||||
const SettingsHeader: FC<OwnProps & DispatchProps> = ({
|
|
||||||
currentScreen,
|
currentScreen,
|
||||||
editedFolderId,
|
editedFolderId,
|
||||||
onReset,
|
onReset,
|
||||||
onSaveFilter,
|
onSaveFilter,
|
||||||
signOut,
|
|
||||||
deleteChatFolder,
|
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
signOut,
|
||||||
|
deleteChatFolder,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const [isSignOutDialogOpen, setIsSignOutDialogOpen] = useState(false);
|
const [isSignOutDialogOpen, setIsSignOutDialogOpen] = useState(false);
|
||||||
const [isDeleteFolderDialogOpen, setIsDeleteFolderDialogOpen] = useState(false);
|
const [isDeleteFolderDialogOpen, setIsDeleteFolderDialogOpen] = useState(false);
|
||||||
|
|
||||||
@ -263,7 +262,4 @@ const SettingsHeader: FC<OwnProps & DispatchProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(withGlobal<OwnProps>(
|
export default memo(SettingsHeader);
|
||||||
undefined,
|
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['signOut', 'deleteChatFolder']),
|
|
||||||
)(SettingsHeader));
|
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useMemo, useState,
|
FC, memo, useCallback, useEffect, useMemo, useState,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ISettings, LangCode, SettingsScreens } from '../../../types';
|
||||||
import { ApiLanguage } from '../../../api/types';
|
import { ApiLanguage } from '../../../api/types';
|
||||||
|
|
||||||
import { setLanguage } from '../../../util/langProvider';
|
import { setLanguage } from '../../../util/langProvider';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
|
|
||||||
import RadioGroup from '../../ui/RadioGroup';
|
import RadioGroup from '../../ui/RadioGroup';
|
||||||
import Loading from '../../ui/Loading';
|
import Loading from '../../ui/Loading';
|
||||||
@ -23,17 +21,18 @@ type OwnProps = {
|
|||||||
|
|
||||||
type StateProps = Pick<ISettings, 'languages' | 'language'>;
|
type StateProps = Pick<ISettings, 'languages' | 'language'>;
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadLanguages' | 'setSettingOption'>;
|
const SettingsLanguage: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const SettingsLanguage: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
isActive,
|
isActive,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
onReset,
|
onReset,
|
||||||
languages,
|
languages,
|
||||||
language,
|
language,
|
||||||
loadLanguages,
|
|
||||||
setSettingOption,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadLanguages,
|
||||||
|
setSettingOption,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const [selectedLanguage, setSelectedLanguage] = useState<string>(language);
|
const [selectedLanguage, setSelectedLanguage] = useState<string>(language);
|
||||||
const [isLoading, markIsLoading, unmarkIsLoading] = useFlag();
|
const [isLoading, markIsLoading, unmarkIsLoading] = useFlag();
|
||||||
|
|
||||||
@ -96,7 +95,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
language: global.settings.byKey.language,
|
language: global.settings.byKey.language,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'loadLanguages', 'setSettingOption',
|
|
||||||
]),
|
|
||||||
)(SettingsLanguage));
|
)(SettingsLanguage));
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
import React, { FC, memo, useEffect } from '../../../lib/teact/teact';
|
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 { SettingsScreens } from '../../../types';
|
||||||
import { ApiUser } from '../../../api/types';
|
import { ApiUser } from '../../../api/types';
|
||||||
|
|
||||||
import { selectUser } from '../../../modules/selectors';
|
import { selectUser } from '../../../modules/selectors';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||||
|
|
||||||
@ -25,16 +23,15 @@ type StateProps = {
|
|||||||
lastSyncTime?: number;
|
lastSyncTime?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadProfilePhotos'>;
|
const SettingsMain: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const SettingsMain: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
isActive,
|
isActive,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
onReset,
|
onReset,
|
||||||
loadProfilePhotos,
|
|
||||||
currentUser,
|
currentUser,
|
||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { loadProfilePhotos } = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const profileId = currentUser?.id;
|
const profileId = currentUser?.id;
|
||||||
|
|
||||||
@ -111,5 +108,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['loadProfilePhotos']),
|
|
||||||
)(SettingsMain));
|
)(SettingsMain));
|
||||||
|
|||||||
@ -3,12 +3,10 @@ import useDebounce from '../../../hooks/useDebounce';
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect,
|
FC, memo, useCallback, useEffect,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { SettingsScreens } from '../../../types';
|
||||||
|
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||||
import { playNotifySound } from '../../../util/notifications';
|
import { playNotifySound } from '../../../util/notifications';
|
||||||
@ -35,12 +33,7 @@ type StateProps = {
|
|||||||
notificationSoundVolume: number;
|
notificationSoundVolume: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
const SettingsNotifications: FC<OwnProps & StateProps> = ({
|
||||||
'loadNotificationSettings' | 'updateContactSignUpNotification' |
|
|
||||||
'updateNotificationSettings' | 'updateWebNotificationSettings'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
isActive,
|
isActive,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
onReset,
|
onReset,
|
||||||
@ -54,11 +47,14 @@ const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
hasPushNotifications,
|
hasPushNotifications,
|
||||||
hasWebNotifications,
|
hasWebNotifications,
|
||||||
notificationSoundVolume,
|
notificationSoundVolume,
|
||||||
loadNotificationSettings,
|
|
||||||
updateContactSignUpNotification,
|
|
||||||
updateNotificationSettings,
|
|
||||||
updateWebNotificationSettings,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadNotificationSettings,
|
||||||
|
updateContactSignUpNotification,
|
||||||
|
updateNotificationSettings,
|
||||||
|
updateWebNotificationSettings,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadNotificationSettings();
|
loadNotificationSettings();
|
||||||
}, [loadNotificationSettings]);
|
}, [loadNotificationSettings]);
|
||||||
@ -147,7 +143,9 @@ const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
subLabel={lang(hasPrivateChatsNotifications ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
|
subLabel={lang(hasPrivateChatsNotifications ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
|
||||||
checked={hasPrivateChatsNotifications}
|
checked={hasPrivateChatsNotifications}
|
||||||
onChange={(e) => { handleSettingsChange(e, 'contact', 'silent'); }}
|
onChange={(e) => {
|
||||||
|
handleSettingsChange(e, 'contact', 'silent');
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={lang('MessagePreview')}
|
label={lang('MessagePreview')}
|
||||||
@ -155,7 +153,9 @@ const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
subLabel={lang(hasPrivateChatsMessagePreview ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
|
subLabel={lang(hasPrivateChatsMessagePreview ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
|
||||||
checked={hasPrivateChatsMessagePreview}
|
checked={hasPrivateChatsMessagePreview}
|
||||||
onChange={(e) => { handleSettingsChange(e, 'contact', 'showPreviews'); }}
|
onChange={(e) => {
|
||||||
|
handleSettingsChange(e, 'contact', 'showPreviews');
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -166,14 +166,18 @@ const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
label={lang('NotificationsForGroups')}
|
label={lang('NotificationsForGroups')}
|
||||||
subLabel={lang(hasGroupNotifications ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
|
subLabel={lang(hasGroupNotifications ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
|
||||||
checked={hasGroupNotifications}
|
checked={hasGroupNotifications}
|
||||||
onChange={(e) => { handleSettingsChange(e, 'group', 'silent'); }}
|
onChange={(e) => {
|
||||||
|
handleSettingsChange(e, 'group', 'silent');
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={lang('MessagePreview')}
|
label={lang('MessagePreview')}
|
||||||
disabled={!hasGroupNotifications}
|
disabled={!hasGroupNotifications}
|
||||||
subLabel={lang(hasGroupMessagePreview ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
|
subLabel={lang(hasGroupMessagePreview ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
|
||||||
checked={hasGroupMessagePreview}
|
checked={hasGroupMessagePreview}
|
||||||
onChange={(e) => { handleSettingsChange(e, 'group', 'showPreviews'); }}
|
onChange={(e) => {
|
||||||
|
handleSettingsChange(e, 'group', 'showPreviews');
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -185,7 +189,9 @@ const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
subLabel={lang(hasBroadcastNotifications ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
|
subLabel={lang(hasBroadcastNotifications ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
|
||||||
checked={hasBroadcastNotifications}
|
checked={hasBroadcastNotifications}
|
||||||
onChange={(e) => { handleSettingsChange(e, 'broadcast', 'silent'); }}
|
onChange={(e) => {
|
||||||
|
handleSettingsChange(e, 'broadcast', 'silent');
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={lang('MessagePreview')}
|
label={lang('MessagePreview')}
|
||||||
@ -193,7 +199,9 @@ const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
subLabel={lang(hasBroadcastMessagePreview ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
|
subLabel={lang(hasBroadcastMessagePreview ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
|
||||||
checked={hasBroadcastMessagePreview}
|
checked={hasBroadcastMessagePreview}
|
||||||
onChange={(e) => { handleSettingsChange(e, 'broadcast', 'showPreviews'); }}
|
onChange={(e) => {
|
||||||
|
handleSettingsChange(e, 'broadcast', 'showPreviews');
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -210,23 +218,19 @@ const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(withGlobal<OwnProps>((global): StateProps => {
|
export default memo(withGlobal<OwnProps>(
|
||||||
return {
|
(global): StateProps => {
|
||||||
hasPrivateChatsNotifications: Boolean(global.settings.byKey.hasPrivateChatsNotifications),
|
return {
|
||||||
hasPrivateChatsMessagePreview: Boolean(global.settings.byKey.hasPrivateChatsMessagePreview),
|
hasPrivateChatsNotifications: Boolean(global.settings.byKey.hasPrivateChatsNotifications),
|
||||||
hasGroupNotifications: Boolean(global.settings.byKey.hasGroupNotifications),
|
hasPrivateChatsMessagePreview: Boolean(global.settings.byKey.hasPrivateChatsMessagePreview),
|
||||||
hasGroupMessagePreview: Boolean(global.settings.byKey.hasGroupMessagePreview),
|
hasGroupNotifications: Boolean(global.settings.byKey.hasGroupNotifications),
|
||||||
hasBroadcastNotifications: Boolean(global.settings.byKey.hasBroadcastNotifications),
|
hasGroupMessagePreview: Boolean(global.settings.byKey.hasGroupMessagePreview),
|
||||||
hasBroadcastMessagePreview: Boolean(global.settings.byKey.hasBroadcastMessagePreview),
|
hasBroadcastNotifications: Boolean(global.settings.byKey.hasBroadcastNotifications),
|
||||||
hasContactJoinedNotifications: Boolean(global.settings.byKey.hasContactJoinedNotifications),
|
hasBroadcastMessagePreview: Boolean(global.settings.byKey.hasBroadcastMessagePreview),
|
||||||
hasWebNotifications: global.settings.byKey.hasWebNotifications,
|
hasContactJoinedNotifications: Boolean(global.settings.byKey.hasContactJoinedNotifications),
|
||||||
hasPushNotifications: global.settings.byKey.hasPushNotifications,
|
hasWebNotifications: global.settings.byKey.hasWebNotifications,
|
||||||
notificationSoundVolume: global.settings.byKey.notificationSoundVolume,
|
hasPushNotifications: global.settings.byKey.hasPushNotifications,
|
||||||
};
|
notificationSoundVolume: global.settings.byKey.notificationSoundVolume,
|
||||||
},
|
};
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
},
|
||||||
'loadNotificationSettings',
|
)(SettingsNotifications));
|
||||||
'updateContactSignUpNotification',
|
|
||||||
'updateNotificationSettings',
|
|
||||||
'updateWebNotificationSettings',
|
|
||||||
]))(SettingsNotifications));
|
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
import React, { FC, memo, useEffect } from '../../../lib/teact/teact';
|
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 { PrivacyVisibility, SettingsScreens } from '../../../types';
|
||||||
|
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||||
|
|
||||||
@ -30,11 +28,7 @@ type StateProps = {
|
|||||||
visibilityPrivacyGroupChats?: PrivacyVisibility;
|
visibilityPrivacyGroupChats?: PrivacyVisibility;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
||||||
'loadBlockedContacts' | 'loadAuthorizations' | 'loadPrivacySettings' | 'loadContentSettings' | 'updateContentSettings'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const SettingsPrivacy: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
isActive,
|
isActive,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
onReset,
|
onReset,
|
||||||
@ -48,12 +42,16 @@ const SettingsPrivacy: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
visibilityPrivacyProfilePhoto,
|
visibilityPrivacyProfilePhoto,
|
||||||
visibilityPrivacyForwarding,
|
visibilityPrivacyForwarding,
|
||||||
visibilityPrivacyGroupChats,
|
visibilityPrivacyGroupChats,
|
||||||
loadPrivacySettings,
|
|
||||||
loadBlockedContacts,
|
|
||||||
loadAuthorizations,
|
|
||||||
loadContentSettings,
|
|
||||||
updateContentSettings,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadPrivacySettings,
|
||||||
|
loadBlockedContacts,
|
||||||
|
loadAuthorizations,
|
||||||
|
loadContentSettings,
|
||||||
|
updateContentSettings,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadBlockedContacts();
|
loadBlockedContacts();
|
||||||
loadAuthorizations();
|
loadAuthorizations();
|
||||||
@ -234,7 +232,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
visibilityPrivacyGroupChats: privacy.chatInvite?.visibility,
|
visibilityPrivacyGroupChats: privacy.chatInvite?.visibility,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'loadBlockedContacts', 'loadAuthorizations', 'loadPrivacySettings', 'loadContentSettings', 'updateContentSettings',
|
|
||||||
]),
|
|
||||||
)(SettingsPrivacy));
|
)(SettingsPrivacy));
|
||||||
|
|||||||
@ -1,13 +1,11 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useMemo,
|
FC, memo, useCallback, useEffect, useMemo,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ApiSession } from '../../../api/types';
|
||||||
import { SettingsScreens } from '../../../types';
|
import { SettingsScreens } from '../../../types';
|
||||||
|
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import { formatPastTimeShort } from '../../../util/dateFormat';
|
import { formatPastTimeShort } from '../../../util/dateFormat';
|
||||||
import useFlag from '../../../hooks/useFlag';
|
import useFlag from '../../../hooks/useFlag';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
@ -26,19 +24,18 @@ type StateProps = {
|
|||||||
activeSessions: ApiSession[];
|
activeSessions: ApiSession[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
const SettingsPrivacyActiveSessions: FC<OwnProps & StateProps> = ({
|
||||||
'loadAuthorizations' | 'terminateAuthorization' | 'terminateAllAuthorizations'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const SettingsPrivacyActiveSessions: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
isActive,
|
isActive,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
onReset,
|
onReset,
|
||||||
activeSessions,
|
activeSessions,
|
||||||
loadAuthorizations,
|
|
||||||
terminateAuthorization,
|
|
||||||
terminateAllAuthorizations,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadAuthorizations,
|
||||||
|
terminateAuthorization,
|
||||||
|
terminateAllAuthorizations,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const [isConfirmTerminateAllDialogOpen, openConfirmTerminateAllDialog, closeConfirmTerminateAllDialog] = useFlag();
|
const [isConfirmTerminateAllDialogOpen, openConfirmTerminateAllDialog, closeConfirmTerminateAllDialog] = useFlag();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadAuthorizations();
|
loadAuthorizations();
|
||||||
@ -162,7 +159,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
activeSessions: global.activeSessions,
|
activeSessions: global.activeSessions,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'loadAuthorizations', 'terminateAuthorization', 'terminateAllAuthorizations',
|
|
||||||
]),
|
|
||||||
)(SettingsPrivacyActiveSessions));
|
)(SettingsPrivacyActiveSessions));
|
||||||
|
|||||||
@ -1,15 +1,13 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback,
|
FC, memo, useCallback,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ApiChat, ApiCountryCode, ApiUser } from '../../../api/types';
|
||||||
import { SettingsScreens } from '../../../types';
|
import { SettingsScreens } from '../../../types';
|
||||||
|
|
||||||
import { CHAT_HEIGHT_PX } from '../../../config';
|
import { CHAT_HEIGHT_PX } from '../../../config';
|
||||||
import { formatPhoneNumberWithCode } from '../../../util/phoneNumber';
|
import { formatPhoneNumberWithCode } from '../../../util/phoneNumber';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import {
|
import {
|
||||||
getChatTitle, getUserFullName, isUserId,
|
getChatTitle, getUserFullName, isUserId,
|
||||||
} from '../../../modules/helpers';
|
} from '../../../modules/helpers';
|
||||||
@ -38,9 +36,7 @@ type StateProps = {
|
|||||||
phoneCodeList: ApiCountryCode[];
|
phoneCodeList: ApiCountryCode[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'unblockContact'>;
|
const SettingsPrivacyBlockedUsers: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const SettingsPrivacyBlockedUsers: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
isActive,
|
isActive,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
onReset,
|
onReset,
|
||||||
@ -48,8 +44,9 @@ const SettingsPrivacyBlockedUsers: FC<OwnProps & StateProps & DispatchProps> = (
|
|||||||
usersByIds,
|
usersByIds,
|
||||||
blockedIds,
|
blockedIds,
|
||||||
phoneCodeList,
|
phoneCodeList,
|
||||||
unblockContact,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { unblockContact } = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const [isBlockUserModalOpen, openBlockUserModal, closeBlockUserModal] = useFlag();
|
const [isBlockUserModalOpen, openBlockUserModal, closeBlockUserModal] = useFlag();
|
||||||
const handleUnblockClick = useCallback((contactId: string) => {
|
const handleUnblockClick = useCallback((contactId: string) => {
|
||||||
@ -158,5 +155,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
phoneCodeList,
|
phoneCodeList,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['unblockContact']),
|
|
||||||
)(SettingsPrivacyBlockedUsers));
|
)(SettingsPrivacyBlockedUsers));
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useMemo,
|
FC, memo, useCallback, useMemo,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ApiChat, ApiUser } from '../../../api/types';
|
||||||
import { ApiPrivacySettings, SettingsScreens } from '../../../types';
|
import { ApiPrivacySettings, SettingsScreens } from '../../../types';
|
||||||
|
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||||
|
|
||||||
import ListItem from '../../ui/ListItem';
|
import ListItem from '../../ui/ListItem';
|
||||||
@ -22,14 +20,13 @@ type OwnProps = {
|
|||||||
onReset: () => void;
|
onReset: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps = Partial<ApiPrivacySettings> & {
|
type StateProps =
|
||||||
chatsById?: Record<string, ApiChat>;
|
Partial<ApiPrivacySettings> & {
|
||||||
usersById?: Record<string, ApiUser>;
|
chatsById?: Record<string, ApiChat>;
|
||||||
};
|
usersById?: Record<string, ApiUser>;
|
||||||
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'setPrivacyVisibility'>;
|
const SettingsPrivacyVisibility: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const SettingsPrivacyVisibility: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
screen,
|
screen,
|
||||||
isActive,
|
isActive,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
@ -40,8 +37,9 @@ const SettingsPrivacyVisibility: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
blockUserIds,
|
blockUserIds,
|
||||||
blockChatIds,
|
blockChatIds,
|
||||||
chatsById,
|
chatsById,
|
||||||
setPrivacyVisibility,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { setPrivacyVisibility } = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const visibilityOptions = useMemo(() => {
|
const visibilityOptions = useMemo(() => {
|
||||||
@ -178,7 +176,9 @@ const SettingsPrivacyVisibility: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
<ListItem
|
<ListItem
|
||||||
narrow
|
narrow
|
||||||
icon="add-user"
|
icon="add-user"
|
||||||
onClick={() => { onScreenSelect(allowedContactsScreen); }}
|
onClick={() => {
|
||||||
|
onScreenSelect(allowedContactsScreen);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className="multiline-menu-item full-size">
|
<div className="multiline-menu-item full-size">
|
||||||
{allowedCount > 0 && <span className="date" dir="auto">+{allowedCount}</span>}
|
{allowedCount > 0 && <span className="date" dir="auto">+{allowedCount}</span>}
|
||||||
@ -191,7 +191,9 @@ const SettingsPrivacyVisibility: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
<ListItem
|
<ListItem
|
||||||
narrow
|
narrow
|
||||||
icon="delete-user"
|
icon="delete-user"
|
||||||
onClick={() => { onScreenSelect(deniedContactsScreen); }}
|
onClick={() => {
|
||||||
|
onScreenSelect(deniedContactsScreen);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className="multiline-menu-item full-size">
|
<div className="multiline-menu-item full-size">
|
||||||
{blockCount > 0 && <span className="date" dir="auto">−{blockCount}</span>}
|
{blockCount > 0 && <span className="date" dir="auto">−{blockCount}</span>}
|
||||||
@ -245,5 +247,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
chatsById,
|
chatsById,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['setPrivacyVisibility']),
|
|
||||||
)(SettingsPrivacyVisibility));
|
)(SettingsPrivacyVisibility));
|
||||||
|
|||||||
@ -1,14 +1,13 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useMemo, useState,
|
FC, memo, useCallback, useMemo, useState,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ApiChat } from '../../../api/types';
|
||||||
import { ApiPrivacySettings, SettingsScreens } from '../../../types';
|
import { ApiPrivacySettings, SettingsScreens } from '../../../types';
|
||||||
|
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import searchWords from '../../../util/searchWords';
|
import searchWords from '../../../util/searchWords';
|
||||||
import { getPrivacyKey } from './helper/privacy';
|
import { getPrivacyKey } from './helper/privacy';
|
||||||
import {
|
import {
|
||||||
@ -37,9 +36,7 @@ type StateProps = {
|
|||||||
settings?: ApiPrivacySettings;
|
settings?: ApiPrivacySettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'setPrivacySettings'>;
|
const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
currentUserId,
|
currentUserId,
|
||||||
isAllowList,
|
isAllowList,
|
||||||
screen,
|
screen,
|
||||||
@ -49,11 +46,12 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps & Dispatc
|
|||||||
orderedPinnedIds,
|
orderedPinnedIds,
|
||||||
archivedListIds,
|
archivedListIds,
|
||||||
archivedPinnedIds,
|
archivedPinnedIds,
|
||||||
setPrivacySettings,
|
|
||||||
isActive,
|
isActive,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
onReset,
|
onReset,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { setPrivacySettings } = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const selectedContactIds = useMemo(() => {
|
const selectedContactIds = useMemo(() => {
|
||||||
@ -105,8 +103,8 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps & Dispatc
|
|||||||
((isUserId(chat.id) && chat.id !== currentUserId) || isChatGroup(chat))
|
((isUserId(chat.id) && chat.id !== currentUserId) || isChatGroup(chat))
|
||||||
&& (
|
&& (
|
||||||
!searchQuery
|
!searchQuery
|
||||||
|| searchWords(getChatTitle(lang, chat), searchQuery)
|
|| searchWords(getChatTitle(lang, chat), searchQuery)
|
||||||
|| selectedContactIds.includes(chat.id)
|
|| selectedContactIds.includes(chat.id)
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
.map(({ id }) => id);
|
.map(({ id }) => id);
|
||||||
@ -196,5 +194,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
settings: getCurrentPrivacySettings(global, screen),
|
settings: getCurrentPrivacySettings(global, screen),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['setPrivacySettings']),
|
|
||||||
)(SettingsPrivacyVisibilityExceptionList));
|
)(SettingsPrivacyVisibilityExceptionList));
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useMemo, useCallback,
|
FC, memo, useMemo, useCallback,
|
||||||
} from '../../../../lib/teact/teact';
|
} 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 { ApiChat } from '../../../../api/types';
|
||||||
import { SettingsScreens } from '../../../../types';
|
import { SettingsScreens } from '../../../../types';
|
||||||
|
|
||||||
import useLang from '../../../../hooks/useLang';
|
import useLang from '../../../../hooks/useLang';
|
||||||
import { pick } from '../../../../util/iteratees';
|
|
||||||
import searchWords from '../../../../util/searchWords';
|
import searchWords from '../../../../util/searchWords';
|
||||||
import { prepareChatList, getChatTitle } from '../../../../modules/helpers';
|
import { prepareChatList, getChatTitle } from '../../../../modules/helpers';
|
||||||
import {
|
import {
|
||||||
@ -39,9 +37,7 @@ type StateProps = {
|
|||||||
archivedPinnedIds?: string[];
|
archivedPinnedIds?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadMoreChats'>;
|
const SettingsFoldersChatFilters: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const SettingsFoldersChatFilters: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
isActive,
|
isActive,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
onReset,
|
onReset,
|
||||||
@ -53,8 +49,9 @@ const SettingsFoldersChatFilters: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
orderedPinnedIds,
|
orderedPinnedIds,
|
||||||
archivedListIds,
|
archivedListIds,
|
||||||
archivedPinnedIds,
|
archivedPinnedIds,
|
||||||
loadMoreChats,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { loadMoreChats } = getDispatch();
|
||||||
|
|
||||||
const { chatFilter } = state;
|
const { chatFilter } = state;
|
||||||
const { selectedChatIds, selectedChatTypes } = selectChatFilters(state, mode, true);
|
const { selectedChatIds, selectedChatTypes } = selectChatFilters(state, mode, true);
|
||||||
|
|
||||||
@ -180,5 +177,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
archivedListIds: listIds.archived,
|
archivedListIds: listIds.archived,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['loadMoreChats']),
|
|
||||||
)(SettingsFoldersChatFilters));
|
)(SettingsFoldersChatFilters));
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useMemo, useState,
|
FC, memo, useCallback, useEffect, useMemo, useState,
|
||||||
} from '../../../../lib/teact/teact';
|
} 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 { SettingsScreens } from '../../../../types';
|
||||||
|
|
||||||
import { STICKER_SIZE_FOLDER_SETTINGS } from '../../../../config';
|
import { STICKER_SIZE_FOLDER_SETTINGS } from '../../../../config';
|
||||||
import { findIntersectionWithSet, pick } from '../../../../util/iteratees';
|
import { findIntersectionWithSet } from '../../../../util/iteratees';
|
||||||
import { isUserId } from '../../../../modules/helpers';
|
import { isUserId } from '../../../../modules/helpers';
|
||||||
import getAnimationData from '../../../common/helpers/animatedAssets';
|
import getAnimationData from '../../../common/helpers/animatedAssets';
|
||||||
import {
|
import {
|
||||||
@ -45,8 +44,6 @@ type StateProps = {
|
|||||||
loadedArchivedChatIds?: string[];
|
loadedArchivedChatIds?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'editChatFolder' | 'addChatFolder' | 'loadMoreChats'>;
|
|
||||||
|
|
||||||
const SUBMIT_TIMEOUT = 500;
|
const SUBMIT_TIMEOUT = 500;
|
||||||
|
|
||||||
const INITIAL_CHATS_LIMIT = 5;
|
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_TITLE = 'Please provide a title for this folder.';
|
||||||
const ERROR_NO_CHATS = 'ChatList.Filter.Error.Empty';
|
const ERROR_NO_CHATS = 'ChatList.Filter.Error.Empty';
|
||||||
|
|
||||||
const SettingsFoldersEdit: FC<OwnProps & StateProps & DispatchProps> = ({
|
const SettingsFoldersEdit: FC<OwnProps & StateProps> = ({
|
||||||
state,
|
state,
|
||||||
dispatch,
|
dispatch,
|
||||||
onAddIncludedChats,
|
onAddIncludedChats,
|
||||||
@ -65,10 +62,13 @@ const SettingsFoldersEdit: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
onBack,
|
onBack,
|
||||||
loadedActiveChatIds,
|
loadedActiveChatIds,
|
||||||
loadedArchivedChatIds,
|
loadedArchivedChatIds,
|
||||||
editChatFolder,
|
|
||||||
addChatFolder,
|
|
||||||
loadMoreChats,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
editChatFolder,
|
||||||
|
addChatFolder,
|
||||||
|
loadMoreChats,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const [animationData, setAnimationData] = useState<Record<string, any>>();
|
const [animationData, setAnimationData] = useState<Record<string, any>>();
|
||||||
const [isAnimationLoaded, setIsAnimationLoaded] = useState(false);
|
const [isAnimationLoaded, setIsAnimationLoaded] = useState(false);
|
||||||
const handleAnimationLoad = useCallback(() => setIsAnimationLoaded(true), []);
|
const handleAnimationLoad = useCallback(() => setIsAnimationLoaded(true), []);
|
||||||
@ -322,5 +322,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
loadedArchivedChatIds: listIds.archived,
|
loadedArchivedChatIds: listIds.archived,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['editChatFolder', 'addChatFolder', 'loadMoreChats']),
|
|
||||||
)(SettingsFoldersEdit));
|
)(SettingsFoldersEdit));
|
||||||
|
|||||||
@ -1,14 +1,13 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useMemo, useCallback, useState, useEffect,
|
FC, memo, useMemo, useCallback, useState, useEffect,
|
||||||
} from '../../../../lib/teact/teact';
|
} 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 { ApiChatFolder, ApiChat, ApiUser } from '../../../../api/types';
|
||||||
import { NotifyException, NotifySettings, SettingsScreens } from '../../../../types';
|
import { NotifyException, NotifySettings, SettingsScreens } from '../../../../types';
|
||||||
|
|
||||||
import { STICKER_SIZE_FOLDER_SETTINGS } from '../../../../config';
|
import { STICKER_SIZE_FOLDER_SETTINGS } from '../../../../config';
|
||||||
import { pick } from '../../../../util/iteratees';
|
|
||||||
import { selectNotifyExceptions, selectNotifySettings } from '../../../../modules/selectors';
|
import { selectNotifyExceptions, selectNotifySettings } from '../../../../modules/selectors';
|
||||||
import { throttle } from '../../../../util/schedulers';
|
import { throttle } from '../../../../util/schedulers';
|
||||||
import getAnimationData from '../../../common/helpers/animatedAssets';
|
import getAnimationData from '../../../common/helpers/animatedAssets';
|
||||||
@ -40,13 +39,11 @@ type StateProps = {
|
|||||||
notifyExceptions?: Record<number, NotifyException>;
|
notifyExceptions?: Record<number, NotifyException>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadRecommendedChatFolders' | 'addChatFolder' | 'showDialog'>;
|
|
||||||
|
|
||||||
const runThrottledForLoadRecommended = throttle((cb) => cb(), 60000, true);
|
const runThrottledForLoadRecommended = throttle((cb) => cb(), 60000, true);
|
||||||
|
|
||||||
const MAX_ALLOWED_FOLDERS = 10;
|
const MAX_ALLOWED_FOLDERS = 10;
|
||||||
|
|
||||||
const SettingsFoldersMain: FC<OwnProps & StateProps & DispatchProps> = ({
|
const SettingsFoldersMain: FC<OwnProps & StateProps> = ({
|
||||||
isActive,
|
isActive,
|
||||||
allListIds,
|
allListIds,
|
||||||
chatsById,
|
chatsById,
|
||||||
@ -60,10 +57,13 @@ const SettingsFoldersMain: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
onEditFolder,
|
onEditFolder,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
onReset,
|
onReset,
|
||||||
loadRecommendedChatFolders,
|
|
||||||
addChatFolder,
|
|
||||||
showDialog,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadRecommendedChatFolders,
|
||||||
|
addChatFolder,
|
||||||
|
showDialog,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const [animationData, setAnimationData] = useState<Record<string, any>>();
|
const [animationData, setAnimationData] = useState<Record<string, any>>();
|
||||||
const [isAnimationLoaded, setIsAnimationLoaded] = useState(false);
|
const [isAnimationLoaded, setIsAnimationLoaded] = useState(false);
|
||||||
const handleAnimationLoad = useCallback(() => setIsAnimationLoaded(true), []);
|
const handleAnimationLoad = useCallback(() => setIsAnimationLoaded(true), []);
|
||||||
@ -250,5 +250,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
notifyExceptions: selectNotifyExceptions(global),
|
notifyExceptions: selectNotifyExceptions(global),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['loadRecommendedChatFolders', 'addChatFolder', 'showDialog']),
|
|
||||||
)(SettingsFoldersMain));
|
)(SettingsFoldersMain));
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect,
|
FC, memo, useCallback, useEffect,
|
||||||
} from '../../../../lib/teact/teact';
|
} 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 { SettingsScreens } from '../../../../types';
|
||||||
|
|
||||||
import { pick } from '../../../../util/iteratees';
|
|
||||||
import { TwoFaDispatch, TwoFaState } from '../../../../hooks/reducers/useTwoFaReducer';
|
import { TwoFaDispatch, TwoFaState } from '../../../../hooks/reducers/useTwoFaReducer';
|
||||||
import useLang from '../../../../hooks/useLang';
|
import useLang from '../../../../hooks/useLang';
|
||||||
|
|
||||||
@ -29,12 +28,7 @@ export type OwnProps = {
|
|||||||
|
|
||||||
type StateProps = GlobalState['twoFaSettings'];
|
type StateProps = GlobalState['twoFaSettings'];
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
const SettingsTwoFa: FC<OwnProps & StateProps> = ({
|
||||||
'updatePassword' | 'updateRecoveryEmail' | 'clearPassword' | 'provideTwoFaEmailCode' |
|
|
||||||
'checkPassword' | 'clearTwoFaError'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const SettingsTwoFa: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
currentScreen,
|
currentScreen,
|
||||||
shownScreen,
|
shownScreen,
|
||||||
state,
|
state,
|
||||||
@ -46,13 +40,16 @@ const SettingsTwoFa: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
isActive,
|
isActive,
|
||||||
onScreenSelect,
|
onScreenSelect,
|
||||||
onReset,
|
onReset,
|
||||||
updatePassword,
|
|
||||||
checkPassword,
|
|
||||||
clearTwoFaError,
|
|
||||||
updateRecoveryEmail,
|
|
||||||
provideTwoFaEmailCode,
|
|
||||||
clearPassword,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
updatePassword,
|
||||||
|
checkPassword,
|
||||||
|
clearTwoFaError,
|
||||||
|
updateRecoveryEmail,
|
||||||
|
provideTwoFaEmailCode,
|
||||||
|
clearPassword,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (waitingEmailCodeLength) {
|
if (waitingEmailCodeLength) {
|
||||||
if (currentScreen === SettingsScreens.TwoFaNewPasswordEmail) {
|
if (currentScreen === SettingsScreens.TwoFaNewPasswordEmail) {
|
||||||
@ -435,8 +432,4 @@ const SettingsTwoFa: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
|
|
||||||
export default memo(withGlobal<OwnProps>(
|
export default memo(withGlobal<OwnProps>(
|
||||||
(global): StateProps => ({ ...global.twoFaSettings }),
|
(global): StateProps => ({ ...global.twoFaSettings }),
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'updatePassword', 'updateRecoveryEmail', 'clearPassword', 'provideTwoFaEmailCode',
|
|
||||||
'checkPassword', 'clearTwoFaError',
|
|
||||||
]),
|
|
||||||
)(SettingsTwoFa));
|
)(SettingsTwoFa));
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import React, { FC, memo } from '../../lib/teact/teact';
|
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 { ApiError, ApiInviteInfo } from '../../api/types';
|
||||||
|
|
||||||
import getReadableErrorText from '../../util/getReadableErrorText';
|
import getReadableErrorText from '../../util/getReadableErrorText';
|
||||||
@ -18,9 +17,9 @@ type StateProps = {
|
|||||||
dialogs: (ApiError | ApiInviteInfo)[];
|
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();
|
const lang = useLang();
|
||||||
|
|
||||||
if (!dialogs.length) {
|
if (!dialogs.length) {
|
||||||
@ -104,5 +103,4 @@ function getErrorHeader(error: ApiError) {
|
|||||||
|
|
||||||
export default memo(withGlobal(
|
export default memo(withGlobal(
|
||||||
(global): StateProps => pick(global, ['dialogs']),
|
(global): StateProps => pick(global, ['dialogs']),
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['dismissDialog', 'acceptInviteConfirmation']),
|
|
||||||
)(Dialogs));
|
)(Dialogs));
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { FC, memo, useEffect } from '../../lib/teact/teact';
|
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 { ApiMediaFormat, ApiMessage } from '../../api/types';
|
||||||
|
|
||||||
import * as mediaLoader from '../../util/mediaLoader';
|
import * as mediaLoader from '../../util/mediaLoader';
|
||||||
@ -9,7 +9,6 @@ import download from '../../util/download';
|
|||||||
import {
|
import {
|
||||||
getMessageContentFilename, getMessageMediaHash,
|
getMessageContentFilename, getMessageMediaHash,
|
||||||
} from '../../modules/helpers';
|
} from '../../modules/helpers';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
|
|
||||||
type StateProps = {
|
type StateProps = {
|
||||||
activeDownloads: Record<number, number[]>;
|
activeDownloads: Record<number, number[]>;
|
||||||
@ -19,15 +18,14 @@ type StateProps = {
|
|||||||
}>;
|
}>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'cancelMessageMediaDownload'>;
|
|
||||||
|
|
||||||
const startedDownloads = new Set<string>();
|
const startedDownloads = new Set<string>();
|
||||||
|
|
||||||
const DownloadManager: FC<StateProps & DispatchProps> = ({
|
const DownloadManager: FC<StateProps> = ({
|
||||||
activeDownloads,
|
activeDownloads,
|
||||||
messages,
|
messages,
|
||||||
cancelMessageMediaDownload,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { cancelMessageMediaDownload } = getDispatch();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Object.entries(activeDownloads).forEach(([chatId, messageIds]) => {
|
Object.entries(activeDownloads).forEach(([chatId, messageIds]) => {
|
||||||
const activeMessages = messageIds.map((id) => messages[Number(chatId)].byId[id]);
|
const activeMessages = messageIds.map((id) => messages[Number(chatId)].byId[id]);
|
||||||
@ -77,5 +75,4 @@ export default memo(withGlobal(
|
|||||||
messages,
|
messages,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['cancelMessageMediaDownload']),
|
|
||||||
)(DownloadManager));
|
)(DownloadManager));
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useMemo, useState, memo, useRef, useCallback,
|
FC, useMemo, useState, memo, useRef, useCallback,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { ApiChat, MAIN_THREAD_ID } from '../../api/types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -12,7 +11,7 @@ import {
|
|||||||
getCanPostInChat,
|
getCanPostInChat,
|
||||||
sortChatIds,
|
sortChatIds,
|
||||||
} from '../../modules/helpers';
|
} from '../../modules/helpers';
|
||||||
import { pick, unique } from '../../util/iteratees';
|
import { unique } from '../../util/iteratees';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
|
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
|
||||||
|
|
||||||
@ -31,9 +30,7 @@ type StateProps = {
|
|||||||
currentUserId?: string;
|
currentUserId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'setForwardChatId' | 'exitForwardMode' | 'loadMoreChats'>;
|
const ForwardPicker: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const ForwardPicker: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
chatsById,
|
chatsById,
|
||||||
activeListIds,
|
activeListIds,
|
||||||
archivedListIds,
|
archivedListIds,
|
||||||
@ -41,10 +38,13 @@ const ForwardPicker: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
contactIds,
|
contactIds,
|
||||||
currentUserId,
|
currentUserId,
|
||||||
isOpen,
|
isOpen,
|
||||||
setForwardChatId,
|
|
||||||
exitForwardMode,
|
|
||||||
loadMoreChats,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
setForwardChatId,
|
||||||
|
exitForwardMode,
|
||||||
|
loadMoreChats,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const [filter, setFilter] = useState('');
|
const [filter, setFilter] = useState('');
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
@ -120,5 +120,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
currentUserId,
|
currentUserId,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['setForwardChatId', 'exitForwardMode', 'loadMoreChats']),
|
|
||||||
)(ForwardPicker));
|
)(ForwardPicker));
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
import React, { FC, memo, useCallback } from '../../lib/teact/teact';
|
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 useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
import CalendarModal from '../common/CalendarModal';
|
import CalendarModal from '../common/CalendarModal';
|
||||||
@ -16,11 +13,11 @@ type StateProps = {
|
|||||||
selectedAt?: number;
|
selectedAt?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'searchMessagesByDate' | 'closeHistoryCalendar'>;
|
const HistoryCalendar: FC<OwnProps & StateProps> = ({
|
||||||
|
isOpen, selectedAt,
|
||||||
const HistoryCalendar: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
isOpen, selectedAt, searchMessagesByDate, closeHistoryCalendar,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { searchMessagesByDate, closeHistoryCalendar } = getDispatch();
|
||||||
|
|
||||||
const handleJumpToDate = useCallback((date: Date) => {
|
const handleJumpToDate = useCallback((date: Date) => {
|
||||||
searchMessagesByDate({ timestamp: date.valueOf() / 1000 });
|
searchMessagesByDate({ timestamp: date.valueOf() / 1000 });
|
||||||
closeHistoryCalendar();
|
closeHistoryCalendar();
|
||||||
@ -44,7 +41,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
(global): StateProps => {
|
(global): StateProps => {
|
||||||
return { selectedAt: global.historyCalendarSelectedAt };
|
return { selectedAt: global.historyCalendarSelectedAt };
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'searchMessagesByDate', 'closeHistoryCalendar',
|
|
||||||
]),
|
|
||||||
)(HistoryCalendar));
|
)(HistoryCalendar));
|
||||||
|
|||||||
@ -1,17 +1,15 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useEffect, memo, useCallback,
|
FC, useEffect, memo, useCallback,
|
||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
import { getGlobal, withGlobal } from '../../lib/teact/teactn';
|
import { getDispatch, getGlobal, withGlobal } from '../../lib/teact/teactn';
|
||||||
|
|
||||||
import { LangCode } from '../../types';
|
import { LangCode } from '../../types';
|
||||||
import { GlobalActions } from '../../global/types';
|
|
||||||
import { ApiMessage } from '../../api/types';
|
import { ApiMessage } from '../../api/types';
|
||||||
|
|
||||||
import '../../modules/actions/all';
|
import '../../modules/actions/all';
|
||||||
import {
|
import {
|
||||||
BASE_EMOJI_KEYWORD_LANG, DEBUG, INACTIVE_MARKER, PAGE_TITLE,
|
BASE_EMOJI_KEYWORD_LANG, DEBUG, INACTIVE_MARKER, PAGE_TITLE,
|
||||||
} from '../../config';
|
} from '../../config';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import {
|
import {
|
||||||
selectChatMessage,
|
selectChatMessage,
|
||||||
selectCountNotMutedUnread,
|
selectCountNotMutedUnread,
|
||||||
@ -72,12 +70,6 @@ type StateProps = {
|
|||||||
isCallFallbackConfirmOpen: boolean;
|
isCallFallbackConfirmOpen: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'loadAnimatedEmojis' | 'loadNotificationSettings' | 'loadNotificationExceptions' | 'updateIsOnline' |
|
|
||||||
'loadTopInlineBots' | 'loadEmojiKeywords' | 'openStickerSetShortName' |
|
|
||||||
'loadCountryList' | 'ensureTimeFormat' | 'checkVersionNotification'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const NOTIFICATION_INTERVAL = 1000;
|
const NOTIFICATION_INTERVAL = 1000;
|
||||||
|
|
||||||
let notificationInterval: number | undefined;
|
let notificationInterval: number | undefined;
|
||||||
@ -85,7 +77,7 @@ let notificationInterval: number | undefined;
|
|||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
let DEBUG_isLogged = false;
|
let DEBUG_isLogged = false;
|
||||||
|
|
||||||
const Main: FC<StateProps & DispatchProps> = ({
|
const Main: FC<StateProps> = ({
|
||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
isLeftColumnShown,
|
isLeftColumnShown,
|
||||||
isRightColumnShown,
|
isRightColumnShown,
|
||||||
@ -104,17 +96,20 @@ const Main: FC<StateProps & DispatchProps> = ({
|
|||||||
language,
|
language,
|
||||||
wasTimeFormatSetManually,
|
wasTimeFormatSetManually,
|
||||||
isCallFallbackConfirmOpen,
|
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) {
|
if (DEBUG && !DEBUG_isLogged) {
|
||||||
DEBUG_isLogged = true;
|
DEBUG_isLogged = true;
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
@ -362,9 +357,4 @@ export default memo(withGlobal(
|
|||||||
isCallFallbackConfirmOpen: Boolean(global.groupCalls.isFallbackConfirmOpen),
|
isCallFallbackConfirmOpen: Boolean(global.groupCalls.isFallbackConfirmOpen),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'loadAnimatedEmojis', 'loadNotificationSettings', 'loadNotificationExceptions', 'updateIsOnline',
|
|
||||||
'loadTopInlineBots', 'loadEmojiKeywords', 'openStickerSetShortName', 'loadCountryList', 'ensureTimeFormat',
|
|
||||||
'checkVersionNotification',
|
|
||||||
]),
|
|
||||||
)(Main));
|
)(Main));
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import React, { FC, memo } from '../../lib/teact/teact';
|
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 { ApiNotification } from '../../api/types';
|
||||||
|
|
||||||
import { pick } from '../../util/iteratees';
|
import { pick } from '../../util/iteratees';
|
||||||
@ -13,9 +12,9 @@ type StateProps = {
|
|||||||
notifications: ApiNotification[];
|
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) {
|
if (!notifications.length) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@ -34,5 +33,4 @@ const Notifications: FC<StateProps & DispatchProps> = ({ notifications, dismissN
|
|||||||
|
|
||||||
export default memo(withGlobal(
|
export default memo(withGlobal(
|
||||||
(global): StateProps => pick(global, ['notifications']),
|
(global): StateProps => pick(global, ['notifications']),
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['dismissNotification']),
|
|
||||||
)(Notifications));
|
)(Notifications));
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
import React, { FC, memo, useCallback } from '../../lib/teact/teact';
|
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 { ensureProtocol } from '../../util/ensureProtocol';
|
||||||
import renderText from '../common/helpers/renderText';
|
import renderText from '../common/helpers/renderText';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
@ -15,9 +12,9 @@ export type OwnProps = {
|
|||||||
url?: string;
|
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 lang = useLang();
|
||||||
|
|
||||||
const handleOpen = useCallback(() => {
|
const handleOpen = useCallback(() => {
|
||||||
@ -43,7 +40,4 @@ const SafeLinkModal: FC<OwnProps & DispatchProps> = ({ url, toggleSafeLinkModal
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(withGlobal<OwnProps>(
|
export default memo(SafeLinkModal);
|
||||||
undefined,
|
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['toggleSafeLinkModal']),
|
|
||||||
)(SafeLinkModal));
|
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useMemo, useRef, useState,
|
FC, memo, useCallback, useEffect, useMemo, useRef, useState,
|
||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../lib/teact/teactn';
|
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
|
||||||
|
|
||||||
import { GlobalActions } from '../../global/types';
|
|
||||||
import {
|
import {
|
||||||
ApiChat, ApiDimensions, ApiMediaFormat, ApiMessage, ApiUser,
|
ApiChat, ApiDimensions, ApiMediaFormat, ApiMessage, ApiUser,
|
||||||
} from '../../api/types';
|
} from '../../api/types';
|
||||||
@ -51,7 +50,6 @@ import { stopCurrentAudio } from '../../util/audioPlayer';
|
|||||||
import captureEscKeyListener from '../../util/captureEscKeyListener';
|
import captureEscKeyListener from '../../util/captureEscKeyListener';
|
||||||
import { captureEvents } from '../../util/captureEvents';
|
import { captureEvents } from '../../util/captureEvents';
|
||||||
import { IS_IOS, IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV } from '../../util/environment';
|
import { IS_IOS, IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV } from '../../util/environment';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import windowSize from '../../util/windowSize';
|
import windowSize from '../../util/windowSize';
|
||||||
import { AVATAR_FULL_DIMENSIONS, MEDIA_VIEWER_MEDIA_QUERY } from '../common/helpers/mediaDimensions';
|
import { AVATAR_FULL_DIMENSIONS, MEDIA_VIEWER_MEDIA_QUERY } from '../common/helpers/mediaDimensions';
|
||||||
import { renderMessageText } from '../common/helpers/renderMessageText';
|
import { renderMessageText } from '../common/helpers/renderMessageText';
|
||||||
@ -83,11 +81,9 @@ type StateProps = {
|
|||||||
animationLevel: 0 | 1 | 2;
|
animationLevel: 0 | 1 | 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'openMediaViewer' | 'closeMediaViewer' | 'openForwardMenu' | 'focusMessage'>;
|
|
||||||
|
|
||||||
const ANIMATION_DURATION = 350;
|
const ANIMATION_DURATION = 350;
|
||||||
|
|
||||||
const MediaViewer: FC<StateProps & DispatchProps> = ({
|
const MediaViewer: FC<StateProps> = ({
|
||||||
chatId,
|
chatId,
|
||||||
threadId,
|
threadId,
|
||||||
messageId,
|
messageId,
|
||||||
@ -98,12 +94,15 @@ const MediaViewer: FC<StateProps & DispatchProps> = ({
|
|||||||
message,
|
message,
|
||||||
chatMessages,
|
chatMessages,
|
||||||
collectionIds,
|
collectionIds,
|
||||||
openMediaViewer,
|
|
||||||
closeMediaViewer,
|
|
||||||
openForwardMenu,
|
|
||||||
focusMessage,
|
|
||||||
animationLevel,
|
animationLevel,
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
openMediaViewer,
|
||||||
|
closeMediaViewer,
|
||||||
|
openForwardMenu,
|
||||||
|
focusMessage,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const isOpen = Boolean(avatarOwner || messageId);
|
const isOpen = Boolean(avatarOwner || messageId);
|
||||||
|
|
||||||
const isFromSharedMedia = origin === MediaViewerOrigin.SharedMedia;
|
const isFromSharedMedia = origin === MediaViewerOrigin.SharedMedia;
|
||||||
@ -641,7 +640,4 @@ export default memo(withGlobal(
|
|||||||
animationLevel,
|
animationLevel,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'openMediaViewer', 'closeMediaViewer', 'openForwardMenu', 'focusMessage',
|
|
||||||
]),
|
|
||||||
)(MediaViewer));
|
)(MediaViewer));
|
||||||
|
|||||||
@ -4,9 +4,8 @@ import React, {
|
|||||||
useCallback,
|
useCallback,
|
||||||
useMemo,
|
useMemo,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { ApiMessage } from '../../api/types';
|
||||||
|
|
||||||
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
@ -14,7 +13,6 @@ import { getMessageMediaHash } from '../../modules/helpers';
|
|||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
import useMediaWithLoadProgress from '../../hooks/useMediaWithLoadProgress';
|
import useMediaWithLoadProgress from '../../hooks/useMediaWithLoadProgress';
|
||||||
import { selectIsDownloading } from '../../modules/selectors';
|
import { selectIsDownloading } from '../../modules/selectors';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
|
|
||||||
import Button from '../ui/Button';
|
import Button from '../ui/Button';
|
||||||
import DropdownMenu from '../ui/DropdownMenu';
|
import DropdownMenu from '../ui/DropdownMenu';
|
||||||
@ -39,9 +37,7 @@ type OwnProps = {
|
|||||||
onZoomToggle: NoneToVoidFunction;
|
onZoomToggle: NoneToVoidFunction;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'downloadMessageMedia' | 'cancelMessageMediaDownload'>;
|
const MediaViewerActions: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const MediaViewerActions: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
mediaData,
|
mediaData,
|
||||||
isVideo,
|
isVideo,
|
||||||
isZoomed,
|
isZoomed,
|
||||||
@ -52,9 +48,12 @@ const MediaViewerActions: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
onCloseMediaViewer,
|
onCloseMediaViewer,
|
||||||
onForward,
|
onForward,
|
||||||
onZoomToggle,
|
onZoomToggle,
|
||||||
downloadMessageMedia,
|
|
||||||
cancelMessageMediaDownload,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
downloadMessageMedia,
|
||||||
|
cancelMessageMediaDownload,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const { loadProgress: downloadProgress } = useMediaWithLoadProgress(
|
const { loadProgress: downloadProgress } = useMediaWithLoadProgress(
|
||||||
message && getMessageMediaHash(message, 'download'),
|
message && getMessageMediaHash(message, 'download'),
|
||||||
!isDownloading,
|
!isDownloading,
|
||||||
@ -193,8 +192,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
isDownloading,
|
isDownloading,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'downloadMessageMedia',
|
|
||||||
'cancelMessageMediaDownload',
|
|
||||||
]),
|
|
||||||
)(MediaViewerActions));
|
)(MediaViewerActions));
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import React, { FC, useCallback } from '../../lib/teact/teact';
|
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 { ApiChat, ApiMessage, ApiUser } from '../../api/types';
|
||||||
|
|
||||||
import { getSenderTitle, isUserId } from '../../modules/helpers';
|
import { getSenderTitle, isUserId } from '../../modules/helpers';
|
||||||
@ -13,7 +12,6 @@ import {
|
|||||||
selectSender,
|
selectSender,
|
||||||
selectUser,
|
selectUser,
|
||||||
} from '../../modules/selectors';
|
} from '../../modules/selectors';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
import Avatar from '../common/Avatar';
|
import Avatar from '../common/Avatar';
|
||||||
@ -31,17 +29,18 @@ type StateProps = {
|
|||||||
message?: ApiMessage;
|
message?: ApiMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'closeMediaViewer' | 'focusMessage'>;
|
const SenderInfo: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const SenderInfo: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
chatId,
|
chatId,
|
||||||
messageId,
|
messageId,
|
||||||
sender,
|
sender,
|
||||||
isAvatar,
|
isAvatar,
|
||||||
message,
|
message,
|
||||||
closeMediaViewer,
|
|
||||||
focusMessage,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
closeMediaViewer,
|
||||||
|
focusMessage,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const handleFocusMessage = useCallback(() => {
|
const handleFocusMessage = useCallback(() => {
|
||||||
closeMediaViewer();
|
closeMediaViewer();
|
||||||
focusMessage({ chatId, messageId });
|
focusMessage({ chatId, messageId });
|
||||||
@ -95,5 +94,4 @@ export default withGlobal<OwnProps>(
|
|||||||
sender: message && selectSender(global, message),
|
sender: message && selectSender(global, message),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['closeMediaViewer', 'focusMessage']),
|
|
||||||
)(SenderInfo);
|
)(SenderInfo);
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useCallback, useEffect, useMemo,
|
FC, useCallback, useEffect, useMemo,
|
||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../lib/teact/teactn';
|
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
|
||||||
|
|
||||||
import { AudioOrigin } from '../../types';
|
import { AudioOrigin } from '../../types';
|
||||||
import { GlobalActions } from '../../global/types';
|
|
||||||
import {
|
import {
|
||||||
ApiAudio, ApiChat, ApiMessage, ApiUser,
|
ApiAudio, ApiChat, ApiMessage, ApiUser,
|
||||||
} from '../../api/types';
|
} from '../../api/types';
|
||||||
@ -16,7 +15,6 @@ import {
|
|||||||
getMediaDuration, getMessageContent, getMessageMediaHash, getSenderTitle, isMessageLocal,
|
getMediaDuration, getMessageContent, getMessageMediaHash, getSenderTitle, isMessageLocal,
|
||||||
} from '../../modules/helpers';
|
} from '../../modules/helpers';
|
||||||
import { selectChat, selectSender } from '../../modules/selectors';
|
import { selectChat, selectSender } from '../../modules/selectors';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
import { makeTrackId } from '../../util/audioPlayer';
|
import { makeTrackId } from '../../util/audioPlayer';
|
||||||
import { clearMediaSession } from '../../util/mediaSession';
|
import { clearMediaSession } from '../../util/mediaSession';
|
||||||
@ -47,17 +45,9 @@ type StateProps = {
|
|||||||
isMuted: boolean;
|
isMuted: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'focusMessage' |
|
|
||||||
'closeAudioPlayer' |
|
|
||||||
'setAudioPlayerVolume' |
|
|
||||||
'setAudioPlayerPlaybackRate' |
|
|
||||||
'setAudioPlayerMuted'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const FAST_PLAYBACK_RATE = 1.8;
|
const FAST_PLAYBACK_RATE = 1.8;
|
||||||
|
|
||||||
const AudioPlayer: FC<OwnProps & StateProps & DispatchProps> = ({
|
const AudioPlayer: FC<OwnProps & StateProps> = ({
|
||||||
message,
|
message,
|
||||||
className,
|
className,
|
||||||
noUi,
|
noUi,
|
||||||
@ -66,12 +56,15 @@ const AudioPlayer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
volume,
|
volume,
|
||||||
playbackRate,
|
playbackRate,
|
||||||
isMuted,
|
isMuted,
|
||||||
setAudioPlayerVolume,
|
|
||||||
setAudioPlayerPlaybackRate,
|
|
||||||
setAudioPlayerMuted,
|
|
||||||
focusMessage,
|
|
||||||
closeAudioPlayer,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
setAudioPlayerVolume,
|
||||||
|
setAudioPlayerPlaybackRate,
|
||||||
|
setAudioPlayerMuted,
|
||||||
|
focusMessage,
|
||||||
|
closeAudioPlayer,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const { audio, voice, video } = getMessageContent(message);
|
const { audio, voice, video } = getMessageContent(message);
|
||||||
const isVoice = Boolean(voice || video);
|
const isVoice = Boolean(voice || video);
|
||||||
@ -293,8 +286,4 @@ export default withGlobal<OwnProps>(
|
|||||||
isMuted,
|
isMuted,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(
|
|
||||||
actions,
|
|
||||||
['focusMessage', 'closeAudioPlayer', 'setAudioPlayerVolume', 'setAudioPlayerPlaybackRate', 'setAudioPlayerMuted'],
|
|
||||||
),
|
|
||||||
)(AudioPlayer);
|
)(AudioPlayer);
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useRef,
|
FC, memo, useCallback, useEffect, useRef,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { ApiSticker, ApiUpdateConnectionStateType } from '../../api/types';
|
||||||
|
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import { selectChat } from '../../modules/selectors';
|
import { selectChat } from '../../modules/selectors';
|
||||||
import { useIntersectionObserver } from '../../hooks/useIntersectionObserver';
|
import { useIntersectionObserver } from '../../hooks/useIntersectionObserver';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
@ -26,18 +24,19 @@ type StateProps = {
|
|||||||
connectionState?: ApiUpdateConnectionStateType;
|
connectionState?: ApiUpdateConnectionStateType;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadGreetingStickers' | 'sendMessage' | 'markMessageListRead'>;
|
|
||||||
|
|
||||||
const INTERSECTION_DEBOUNCE_MS = 200;
|
const INTERSECTION_DEBOUNCE_MS = 200;
|
||||||
|
|
||||||
const ContactGreeting: FC<OwnProps & StateProps & DispatchProps> = ({
|
const ContactGreeting: FC<OwnProps & StateProps> = ({
|
||||||
sticker,
|
sticker,
|
||||||
connectionState,
|
connectionState,
|
||||||
lastUnreadMessageId,
|
lastUnreadMessageId,
|
||||||
loadGreetingStickers,
|
|
||||||
sendMessage,
|
|
||||||
markMessageListRead,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadGreetingStickers,
|
||||||
|
sendMessage,
|
||||||
|
markMessageListRead,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
@ -110,7 +109,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
connectionState: global.connectionState,
|
connectionState: global.connectionState,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'loadGreetingStickers', 'sendMessage', 'markMessageListRead',
|
|
||||||
]),
|
|
||||||
)(ContactGreeting));
|
)(ContactGreeting));
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useCallback, memo, useEffect,
|
FC, useCallback, memo, useEffect,
|
||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../lib/teact/teactn';
|
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
|
||||||
|
|
||||||
import { GlobalActions } from '../../global/types';
|
|
||||||
|
|
||||||
import { selectCanDeleteSelectedMessages, selectCurrentChat, selectUser } from '../../modules/selectors';
|
import { selectCanDeleteSelectedMessages, selectCurrentChat, selectUser } from '../../modules/selectors';
|
||||||
import {
|
import {
|
||||||
@ -14,7 +12,6 @@ import {
|
|||||||
isChatSuperGroup,
|
isChatSuperGroup,
|
||||||
} from '../../modules/helpers';
|
} from '../../modules/helpers';
|
||||||
import renderText from '../common/helpers/renderText';
|
import renderText from '../common/helpers/renderText';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
import usePrevious from '../../hooks/usePrevious';
|
import usePrevious from '../../hooks/usePrevious';
|
||||||
|
|
||||||
@ -35,9 +32,7 @@ type StateProps = {
|
|||||||
willDeleteForAll?: boolean;
|
willDeleteForAll?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'deleteMessages' | 'exitMessageSelectMode' | 'deleteScheduledMessages'>;
|
const DeleteSelectedMessageModal: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const DeleteSelectedMessageModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
isOpen,
|
isOpen,
|
||||||
isSchedule,
|
isSchedule,
|
||||||
selectedMessageIds,
|
selectedMessageIds,
|
||||||
@ -46,10 +41,13 @@ const DeleteSelectedMessageModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
willDeleteForCurrentUserOnly,
|
willDeleteForCurrentUserOnly,
|
||||||
willDeleteForAll,
|
willDeleteForAll,
|
||||||
onClose,
|
onClose,
|
||||||
deleteMessages,
|
|
||||||
deleteScheduledMessages,
|
|
||||||
exitMessageSelectMode,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
deleteMessages,
|
||||||
|
deleteScheduledMessages,
|
||||||
|
exitMessageSelectMode,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const prevIsOpen = usePrevious(isOpen);
|
const prevIsOpen = usePrevious(isOpen);
|
||||||
|
|
||||||
const handleDeleteMessageForAll = useCallback(() => {
|
const handleDeleteMessageForAll = useCallback(() => {
|
||||||
@ -130,9 +128,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
willDeleteForAll,
|
willDeleteForAll,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'deleteMessages',
|
|
||||||
'deleteScheduledMessages',
|
|
||||||
'exitMessageSelectMode',
|
|
||||||
]),
|
|
||||||
)(DeleteSelectedMessageModal));
|
)(DeleteSelectedMessageModal));
|
||||||
|
|||||||
@ -5,14 +5,13 @@ import React, {
|
|||||||
useCallback,
|
useCallback,
|
||||||
useState,
|
useState,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { MAIN_THREAD_ID } from '../../api/types';
|
||||||
import { IAnchorPosition } from '../../types';
|
import { IAnchorPosition } from '../../types';
|
||||||
|
|
||||||
import { ARE_CALLS_SUPPORTED, IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
import { ARE_CALLS_SUPPORTED, IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import {
|
import {
|
||||||
isChatBasicGroup, isChatChannel, isChatSuperGroup, isUserId,
|
isChatBasicGroup, isChatChannel, isChatSuperGroup, isUserId,
|
||||||
} from '../../modules/helpers';
|
} from '../../modules/helpers';
|
||||||
@ -52,14 +51,10 @@ interface StateProps {
|
|||||||
canCreateVoiceChat?: boolean;
|
canCreateVoiceChat?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'joinChannel' | 'sendBotCommand' | 'openLocalTextSearch' | 'restartBot' | 'openCallFallbackConfirm'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
// Chrome breaks layout when focusing input during transition
|
// Chrome breaks layout when focusing input during transition
|
||||||
const SEARCH_FOCUS_DELAY_MS = 400;
|
const SEARCH_FOCUS_DELAY_MS = 400;
|
||||||
|
|
||||||
const HeaderActions: FC<OwnProps & StateProps & DispatchProps> = ({
|
const HeaderActions: FC<OwnProps & StateProps> = ({
|
||||||
chatId,
|
chatId,
|
||||||
threadId,
|
threadId,
|
||||||
noMenu,
|
noMenu,
|
||||||
@ -75,12 +70,15 @@ const HeaderActions: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
canCreateVoiceChat,
|
canCreateVoiceChat,
|
||||||
isRightColumnShown,
|
isRightColumnShown,
|
||||||
canExpandActions,
|
canExpandActions,
|
||||||
joinChannel,
|
|
||||||
sendBotCommand,
|
|
||||||
openLocalTextSearch,
|
|
||||||
restartBot,
|
|
||||||
openCallFallbackConfirm,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
joinChannel,
|
||||||
|
sendBotCommand,
|
||||||
|
openLocalTextSearch,
|
||||||
|
restartBot,
|
||||||
|
openCallFallbackConfirm,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const menuButtonRef = useRef<HTMLButtonElement>(null);
|
const menuButtonRef = useRef<HTMLButtonElement>(null);
|
||||||
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||||
@ -275,7 +273,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
canCreateVoiceChat,
|
canCreateVoiceChat,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'joinChannel', 'sendBotCommand', 'openLocalTextSearch', 'restartBot', 'openCallFallbackConfirm',
|
|
||||||
]),
|
|
||||||
)(HeaderActions));
|
)(HeaderActions));
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useState,
|
FC, memo, useCallback, useEffect, useState,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { ApiChat } from '../../api/types';
|
||||||
import { IAnchorPosition } from '../../types';
|
import { IAnchorPosition } from '../../types';
|
||||||
|
|
||||||
@ -12,7 +11,6 @@ import { disableScrolling, enableScrolling } from '../../util/scrollLock';
|
|||||||
import {
|
import {
|
||||||
selectChat, selectNotifySettings, selectNotifyExceptions, selectUser,
|
selectChat, selectNotifySettings, selectNotifyExceptions, selectUser,
|
||||||
} from '../../modules/selectors';
|
} from '../../modules/selectors';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import {
|
import {
|
||||||
isUserId, getCanDeleteChat, selectIsChatMuted, getCanAddContact,
|
isUserId, getCanDeleteChat, selectIsChatMuted, getCanAddContact,
|
||||||
} from '../../modules/helpers';
|
} from '../../modules/helpers';
|
||||||
@ -26,11 +24,6 @@ import DeleteChatModal from '../common/DeleteChatModal';
|
|||||||
|
|
||||||
import './HeaderMenuContainer.scss';
|
import './HeaderMenuContainer.scss';
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'updateChatMutedState' | 'enterMessageSelectMode' | 'sendBotCommand' | 'restartBot' | 'openLinkedChat' |
|
|
||||||
'joinGroupCall' | 'createGroupCall' | 'addContact' | 'openCallFallbackConfirm'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
export type OwnProps = {
|
export type OwnProps = {
|
||||||
chatId: string;
|
chatId: string;
|
||||||
threadId: number;
|
threadId: number;
|
||||||
@ -62,7 +55,7 @@ type StateProps = {
|
|||||||
hasLinkedChat?: boolean;
|
hasLinkedChat?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const HeaderMenuContainer: FC<OwnProps & StateProps & DispatchProps> = ({
|
const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
||||||
chatId,
|
chatId,
|
||||||
isOpen,
|
isOpen,
|
||||||
withExtraActions,
|
withExtraActions,
|
||||||
@ -87,16 +80,19 @@ const HeaderMenuContainer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
onSearchClick,
|
onSearchClick,
|
||||||
onClose,
|
onClose,
|
||||||
onCloseAnimationEnd,
|
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 [isMenuOpen, setIsMenuOpen] = useState(true);
|
||||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||||
const { x, y } = anchor;
|
const { x, y } = anchor;
|
||||||
@ -313,15 +309,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
hasLinkedChat: Boolean(chat?.fullInfo?.linkedChatId),
|
hasLinkedChat: Boolean(chat?.fullInfo?.linkedChatId),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'updateChatMutedState',
|
|
||||||
'enterMessageSelectMode',
|
|
||||||
'sendBotCommand',
|
|
||||||
'restartBot',
|
|
||||||
'joinGroupCall',
|
|
||||||
'createGroupCall',
|
|
||||||
'openLinkedChat',
|
|
||||||
'addContact',
|
|
||||||
'openCallFallbackConfirm',
|
|
||||||
]),
|
|
||||||
)(HeaderMenuContainer));
|
)(HeaderMenuContainer));
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useMemo, useRef, useState,
|
FC, memo, useCallback, useEffect, useMemo, useRef, useState,
|
||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
import { getGlobal, withGlobal } from '../../lib/teact/teactn';
|
import { getDispatch, getGlobal, withGlobal } from '../../lib/teact/teactn';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ApiMessage, ApiRestrictionReason, MAIN_THREAD_ID,
|
ApiMessage, ApiRestrictionReason, MAIN_THREAD_ID,
|
||||||
} from '../../api/types';
|
} from '../../api/types';
|
||||||
import { GlobalActions, MessageListType } from '../../global/types';
|
import { MessageListType } from '../../global/types';
|
||||||
import { LoadMoreDirection } from '../../types';
|
import { LoadMoreDirection } from '../../types';
|
||||||
|
|
||||||
import { ANIMATION_END_DELAY, LOCAL_MESSAGE_ID_BASE, MESSAGE_LIST_SLICE } from '../../config';
|
import { ANIMATION_END_DELAY, LOCAL_MESSAGE_ID_BASE, MESSAGE_LIST_SLICE } from '../../config';
|
||||||
@ -32,7 +32,7 @@ import {
|
|||||||
isChatWithRepliesBot,
|
isChatWithRepliesBot,
|
||||||
isChatGroup,
|
isChatGroup,
|
||||||
} from '../../modules/helpers';
|
} from '../../modules/helpers';
|
||||||
import { orderBy, pick } from '../../util/iteratees';
|
import { orderBy } from '../../util/iteratees';
|
||||||
import { fastRaf, debounce, onTickEnd } from '../../util/schedulers';
|
import { fastRaf, debounce, onTickEnd } from '../../util/schedulers';
|
||||||
import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps';
|
import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps';
|
||||||
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
|
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
|
||||||
@ -91,8 +91,6 @@ type StateProps = {
|
|||||||
hasLinkedChat?: boolean;
|
hasLinkedChat?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadViewportMessages' | 'setScrollOffset' | 'openHistoryCalendar'>;
|
|
||||||
|
|
||||||
const BOTTOM_THRESHOLD = 20;
|
const BOTTOM_THRESHOLD = 20;
|
||||||
const UNREAD_DIVIDER_TOP = 10;
|
const UNREAD_DIVIDER_TOP = 10;
|
||||||
const UNREAD_DIVIDER_TOP_WITH_TOOLS = 60;
|
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 runDebouncedForScroll = debounce((cb) => cb(), SCROLL_DEBOUNCE, false);
|
||||||
|
|
||||||
const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
|
const MessageList: FC<OwnProps & StateProps> = ({
|
||||||
chatId,
|
chatId,
|
||||||
threadId,
|
threadId,
|
||||||
type,
|
type,
|
||||||
@ -129,15 +127,14 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
restrictionReason,
|
restrictionReason,
|
||||||
focusingId,
|
focusingId,
|
||||||
isSelectModeActive,
|
isSelectModeActive,
|
||||||
loadViewportMessages,
|
|
||||||
setScrollOffset,
|
|
||||||
lastMessage,
|
lastMessage,
|
||||||
botDescription,
|
botDescription,
|
||||||
threadTopMessageId,
|
threadTopMessageId,
|
||||||
hasLinkedChat,
|
hasLinkedChat,
|
||||||
withBottomShift,
|
withBottomShift,
|
||||||
openHistoryCalendar,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { loadViewportMessages, setScrollOffset } = getDispatch();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
@ -530,7 +527,6 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
noAppearanceAnimation={!messageGroups || !shouldAnimateAppearanceRef.current}
|
noAppearanceAnimation={!messageGroups || !shouldAnimateAppearanceRef.current}
|
||||||
onFabToggle={onFabToggle}
|
onFabToggle={onFabToggle}
|
||||||
onNotchToggle={onNotchToggle}
|
onNotchToggle={onNotchToggle}
|
||||||
openHistoryCalendar={openHistoryCalendar}
|
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Loading color="white" />
|
<Loading color="white" />
|
||||||
@ -602,9 +598,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
...(withLastMessageWhenPreloading && { lastMessage }),
|
...(withLastMessageWhenPreloading && { lastMessage }),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'loadViewportMessages',
|
|
||||||
'setScrollOffset',
|
|
||||||
'openHistoryCalendar',
|
|
||||||
]),
|
|
||||||
)(MessageList));
|
)(MessageList));
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import useMessageObservers from './hooks/useMessageObservers';
|
|||||||
|
|
||||||
import Message from './message/Message';
|
import Message from './message/Message';
|
||||||
import ActionMessage from './ActionMessage';
|
import ActionMessage from './ActionMessage';
|
||||||
|
import { getDispatch } from '../../lib/teact/teactn';
|
||||||
|
|
||||||
interface OwnProps {
|
interface OwnProps {
|
||||||
messageIds: number[];
|
messageIds: number[];
|
||||||
@ -39,7 +40,6 @@ interface OwnProps {
|
|||||||
noAppearanceAnimation: boolean;
|
noAppearanceAnimation: boolean;
|
||||||
onFabToggle: AnyToVoidFunction;
|
onFabToggle: AnyToVoidFunction;
|
||||||
onNotchToggle: AnyToVoidFunction;
|
onNotchToggle: AnyToVoidFunction;
|
||||||
openHistoryCalendar: Function;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const UNREAD_DIVIDER_CLASS = 'unread-divider';
|
const UNREAD_DIVIDER_CLASS = 'unread-divider';
|
||||||
@ -66,8 +66,9 @@ const MessageListContent: FC<OwnProps> = ({
|
|||||||
noAppearanceAnimation,
|
noAppearanceAnimation,
|
||||||
onFabToggle,
|
onFabToggle,
|
||||||
onNotchToggle,
|
onNotchToggle,
|
||||||
openHistoryCalendar,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { openHistoryCalendar } = getDispatch();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
observeIntersectionForMedia,
|
observeIntersectionForMedia,
|
||||||
observeIntersectionForReading,
|
observeIntersectionForReading,
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect,
|
FC, memo, useCallback, useEffect,
|
||||||
} from '../../lib/teact/teact';
|
} 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 {
|
import {
|
||||||
selectCanDeleteSelectedMessages,
|
selectCanDeleteSelectedMessages,
|
||||||
@ -12,7 +12,6 @@ import {
|
|||||||
selectCurrentMessageList,
|
selectCurrentMessageList,
|
||||||
selectSelectedMessagesCount,
|
selectSelectedMessagesCount,
|
||||||
} from '../../modules/selectors';
|
} from '../../modules/selectors';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import useFlag from '../../hooks/useFlag';
|
import useFlag from '../../hooks/useFlag';
|
||||||
import captureKeyboardListeners from '../../util/captureKeyboardListeners';
|
import captureKeyboardListeners from '../../util/captureKeyboardListeners';
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
@ -41,11 +40,7 @@ type StateProps = {
|
|||||||
selectedMessageIds?: number[];
|
selectedMessageIds?: number[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
const MessageSelectToolbar: FC<OwnProps & StateProps> = ({
|
||||||
'exitMessageSelectMode' | 'openForwardMenuForSelectedMessages' | 'downloadSelectedMessages'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const MessageSelectToolbar: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
canPost,
|
canPost,
|
||||||
isActive,
|
isActive,
|
||||||
messageListType,
|
messageListType,
|
||||||
@ -55,10 +50,13 @@ const MessageSelectToolbar: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
canReportMessages,
|
canReportMessages,
|
||||||
canDownloadMessages,
|
canDownloadMessages,
|
||||||
selectedMessageIds,
|
selectedMessageIds,
|
||||||
exitMessageSelectMode,
|
|
||||||
openForwardMenuForSelectedMessages,
|
|
||||||
downloadSelectedMessages,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
exitMessageSelectMode,
|
||||||
|
openForwardMenuForSelectedMessages,
|
||||||
|
downloadSelectedMessages,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const [isDeleteModalOpen, openDeleteModal, closeDeleteModal] = useFlag();
|
const [isDeleteModalOpen, openDeleteModal, closeDeleteModal] = useFlag();
|
||||||
const [isReportModalOpen, openReportModal, closeReportModal] = useFlag();
|
const [isReportModalOpen, openReportModal, closeReportModal] = useFlag();
|
||||||
|
|
||||||
@ -171,7 +169,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
selectedMessageIds,
|
selectedMessageIds,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'exitMessageSelectMode', 'openForwardMenuForSelectedMessages', 'downloadSelectedMessages',
|
|
||||||
]),
|
|
||||||
)(MessageSelectToolbar));
|
)(MessageSelectToolbar));
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useEffect, useState, memo, useMemo, useCallback,
|
FC, useEffect, useState, memo, useMemo, useCallback,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { 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 { ThemeKey } from '../../types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -43,7 +43,6 @@ import {
|
|||||||
getCanPostInChat, getMessageSendingRestrictionReason, isChatChannel, isChatSuperGroup, isUserId,
|
getCanPostInChat, getMessageSendingRestrictionReason, isChatChannel, isChatSuperGroup, isUserId,
|
||||||
} from '../../modules/helpers';
|
} from '../../modules/helpers';
|
||||||
import captureEscKeyListener from '../../util/captureEscKeyListener';
|
import captureEscKeyListener from '../../util/captureEscKeyListener';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
import { createMessageHash } from '../../util/routing';
|
import { createMessageHash } from '../../util/routing';
|
||||||
import useCustomBackground from '../../hooks/useCustomBackground';
|
import useCustomBackground from '../../hooks/useCustomBackground';
|
||||||
@ -104,18 +103,13 @@ type StateProps = {
|
|||||||
canRestartBot?: boolean;
|
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;
|
const CLOSE_ANIMATION_DURATION = IS_SINGLE_COLUMN_LAYOUT ? 450 + ANIMATION_END_DELAY : undefined;
|
||||||
|
|
||||||
function isImage(item: DataTransferItem) {
|
function isImage(item: DataTransferItem) {
|
||||||
return item.kind === 'file' && item.type && SUPPORTED_IMAGE_CONTENT_TYPES.has(item.type);
|
return item.kind === 'file' && item.type && SUPPORTED_IMAGE_CONTENT_TYPES.has(item.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
const MiddleColumn: FC<StateProps & DispatchProps> = ({
|
const MiddleColumn: FC<StateProps> = ({
|
||||||
chatId,
|
chatId,
|
||||||
threadId,
|
threadId,
|
||||||
messageListType,
|
messageListType,
|
||||||
@ -146,17 +140,20 @@ const MiddleColumn: FC<StateProps & DispatchProps> = ({
|
|||||||
canSubscribe,
|
canSubscribe,
|
||||||
canStartBot,
|
canStartBot,
|
||||||
canRestartBot,
|
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 { width: windowWidth } = useWindowSize();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
@ -588,10 +585,6 @@ export default memo(withGlobal(
|
|||||||
canRestartBot,
|
canRestartBot,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'openChat', 'unpinAllMessages', 'loadUser', 'closeLocalTextSearch', 'exitMessageSelectMode',
|
|
||||||
'closePaymentModal', 'clearReceipt', 'joinChannel', 'sendBotCommand', 'restartBot',
|
|
||||||
]),
|
|
||||||
)(MiddleColumn));
|
)(MiddleColumn));
|
||||||
|
|
||||||
function useIsReady(
|
function useIsReady(
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useCallback, useMemo, memo, useEffect, useRef, useState,
|
FC, useCallback, useMemo, memo, useEffect, useRef, useState,
|
||||||
} from '../../lib/teact/teact';
|
} 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 cycleRestrict from '../../util/cycleRestrict';
|
||||||
|
|
||||||
import { GlobalActions, MessageListType } from '../../global/types';
|
import { MessageListType } from '../../global/types';
|
||||||
import {
|
import {
|
||||||
ApiMessage,
|
ApiMessage,
|
||||||
ApiChat,
|
ApiChat,
|
||||||
@ -48,7 +48,6 @@ import useEnsureMessage from '../../hooks/useEnsureMessage';
|
|||||||
import useWindowSize from '../../hooks/useWindowSize';
|
import useWindowSize from '../../hooks/useWindowSize';
|
||||||
import useShowTransition from '../../hooks/useShowTransition';
|
import useShowTransition from '../../hooks/useShowTransition';
|
||||||
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
|
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import { formatIntegerCompact } from '../../util/textFormat';
|
import { formatIntegerCompact } from '../../util/textFormat';
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
@ -96,12 +95,7 @@ type StateProps = {
|
|||||||
connectionState?: ApiUpdateConnectionStateType;
|
connectionState?: ApiUpdateConnectionStateType;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
const MiddleHeader: FC<OwnProps & StateProps> = ({
|
||||||
'openChatWithInfo' | 'pinMessage' | 'focusMessage' | 'openChat' | 'openPreviousChat' | 'loadPinnedMessages' |
|
|
||||||
'toggleLeftColumn' | 'exitMessageSelectMode'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const MiddleHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
chatId,
|
chatId,
|
||||||
threadId,
|
threadId,
|
||||||
messageListType,
|
messageListType,
|
||||||
@ -124,15 +118,18 @@ const MiddleHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
shouldSkipHistoryAnimations,
|
shouldSkipHistoryAnimations,
|
||||||
currentTransitionKey,
|
currentTransitionKey,
|
||||||
connectionState,
|
connectionState,
|
||||||
openChatWithInfo,
|
|
||||||
pinMessage,
|
|
||||||
focusMessage,
|
|
||||||
openChat,
|
|
||||||
openPreviousChat,
|
|
||||||
loadPinnedMessages,
|
|
||||||
toggleLeftColumn,
|
|
||||||
exitMessageSelectMode,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
openChatWithInfo,
|
||||||
|
pinMessage,
|
||||||
|
focusMessage,
|
||||||
|
openChat,
|
||||||
|
openPreviousChat,
|
||||||
|
loadPinnedMessages,
|
||||||
|
toggleLeftColumn,
|
||||||
|
exitMessageSelectMode,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const isBackButtonActive = useRef(true);
|
const isBackButtonActive = useRef(true);
|
||||||
|
|
||||||
@ -523,14 +520,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
|
|
||||||
return state;
|
return state;
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'openChatWithInfo',
|
|
||||||
'pinMessage',
|
|
||||||
'focusMessage',
|
|
||||||
'openChat',
|
|
||||||
'openPreviousChat',
|
|
||||||
'loadPinnedMessages',
|
|
||||||
'toggleLeftColumn',
|
|
||||||
'exitMessageSelectMode',
|
|
||||||
]),
|
|
||||||
)(MiddleHeader));
|
)(MiddleHeader));
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useRef, useState, useLayoutEffect,
|
FC, memo, useCallback, useEffect, useRef, useState, useLayoutEffect,
|
||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../lib/teact/teactn';
|
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
|
||||||
|
|
||||||
import { ApiChat } from '../../api/types';
|
import { ApiChat } from '../../api/types';
|
||||||
import { GlobalActions } from '../../global/types';
|
|
||||||
|
|
||||||
import { debounce } from '../../util/schedulers';
|
import { debounce } from '../../util/schedulers';
|
||||||
import { selectCurrentTextSearch, selectCurrentChat } from '../../modules/selectors';
|
import { selectCurrentTextSearch, selectCurrentChat } from '../../modules/selectors';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import { getDayStartAt } from '../../util/dateFormat';
|
import { getDayStartAt } from '../../util/dateFormat';
|
||||||
|
|
||||||
import Button from '../ui/Button';
|
import Button from '../ui/Button';
|
||||||
@ -29,26 +27,24 @@ type StateProps = {
|
|||||||
isHistoryCalendarOpen?: boolean;
|
isHistoryCalendarOpen?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'setLocalTextSearchQuery' | 'searchTextMessagesLocal' | 'closeLocalTextSearch' | 'openHistoryCalendar' |
|
|
||||||
'focusMessage'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const runDebouncedForSearch = debounce((cb) => cb(), 200, false);
|
const runDebouncedForSearch = debounce((cb) => cb(), 200, false);
|
||||||
|
|
||||||
const MobileSearchFooter: FC<StateProps & DispatchProps> = ({
|
const MobileSearchFooter: FC<StateProps> = ({
|
||||||
isActive,
|
isActive,
|
||||||
chat,
|
chat,
|
||||||
query,
|
query,
|
||||||
totalCount,
|
totalCount,
|
||||||
foundIds,
|
foundIds,
|
||||||
isHistoryCalendarOpen,
|
isHistoryCalendarOpen,
|
||||||
setLocalTextSearchQuery,
|
|
||||||
searchTextMessagesLocal,
|
|
||||||
focusMessage,
|
|
||||||
closeLocalTextSearch,
|
|
||||||
openHistoryCalendar,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
setLocalTextSearchQuery,
|
||||||
|
searchTextMessagesLocal,
|
||||||
|
focusMessage,
|
||||||
|
closeLocalTextSearch,
|
||||||
|
openHistoryCalendar,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
const [focusedIndex, setFocusedIndex] = useState(0);
|
const [focusedIndex, setFocusedIndex] = useState(0);
|
||||||
@ -218,11 +214,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
isHistoryCalendarOpen: Boolean(global.historyCalendarSelectedAt),
|
isHistoryCalendarOpen: Boolean(global.historyCalendarSelectedAt),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'setLocalTextSearchQuery',
|
|
||||||
'searchTextMessagesLocal',
|
|
||||||
'focusMessage',
|
|
||||||
'closeLocalTextSearch',
|
|
||||||
'openHistoryCalendar',
|
|
||||||
]),
|
|
||||||
)(MobileSearchFooter));
|
)(MobileSearchFooter));
|
||||||
|
|||||||
@ -1,15 +1,14 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useCallback, memo, useRef,
|
FC, useCallback, memo, useRef,
|
||||||
} from '../../lib/teact/teact';
|
} 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 { MAIN_THREAD_ID } from '../../api/types';
|
||||||
|
|
||||||
import { selectChat, selectCurrentMessageList } from '../../modules/selectors';
|
import { selectChat, selectCurrentMessageList } from '../../modules/selectors';
|
||||||
import { formatIntegerCompact } from '../../util/textFormat';
|
import { formatIntegerCompact } from '../../util/textFormat';
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
import { pick } from '../../util/iteratees';
|
|
||||||
import fastSmoothScroll from '../../util/fastSmoothScroll';
|
import fastSmoothScroll from '../../util/fastSmoothScroll';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
@ -28,18 +27,17 @@ type StateProps = {
|
|||||||
unreadCount?: number;
|
unreadCount?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'focusNextReply'>;
|
|
||||||
|
|
||||||
const FOCUS_MARGIN = 20;
|
const FOCUS_MARGIN = 20;
|
||||||
|
|
||||||
const ScrollDownButton: FC<OwnProps & StateProps & DispatchProps> = ({
|
const ScrollDownButton: FC<OwnProps & StateProps> = ({
|
||||||
isShown,
|
isShown,
|
||||||
canPost,
|
canPost,
|
||||||
messageListType,
|
messageListType,
|
||||||
unreadCount,
|
unreadCount,
|
||||||
withExtraShift,
|
withExtraShift,
|
||||||
focusNextReply,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { focusNextReply } = getDispatch();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const elementRef = useRef<HTMLDivElement>(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,
|
unreadCount: chat && threadId === MAIN_THREAD_ID && messageListType === 'thread' ? chat.unreadCount : undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['focusNextReply']),
|
|
||||||
)(ScrollDownButton));
|
)(ScrollDownButton));
|
||||||
|
|||||||
@ -1,17 +1,15 @@
|
|||||||
import React, { FC, memo, useCallback } from '../../../lib/teact/teact';
|
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 { ApiBotCommand } from '../../../api/types';
|
||||||
|
|
||||||
import { IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV } from '../../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV } from '../../../util/environment';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import useMouseInside from '../../../hooks/useMouseInside';
|
import useMouseInside from '../../../hooks/useMouseInside';
|
||||||
|
|
||||||
import Menu from '../../ui/Menu';
|
import Menu from '../../ui/Menu';
|
||||||
import BotCommand from './BotCommand';
|
import BotCommand from './BotCommand';
|
||||||
|
|
||||||
import './BotCommandMenu.scss';
|
import './BotCommandMenu.scss';
|
||||||
|
import { getDispatch } from '../../../lib/teact/teactn';
|
||||||
|
|
||||||
export type OwnProps = {
|
export type OwnProps = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@ -19,11 +17,11 @@ export type OwnProps = {
|
|||||||
onClose: NoneToVoidFunction;
|
onClose: NoneToVoidFunction;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'sendBotCommand'>;
|
const BotCommandMenu: FC<OwnProps> = ({
|
||||||
|
isOpen, botCommands, onClose,
|
||||||
const BotCommandMenu: FC<OwnProps & DispatchProps> = ({
|
|
||||||
isOpen, botCommands, onClose, sendBotCommand,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { sendBotCommand } = getDispatch();
|
||||||
|
|
||||||
const [handleMouseEnter, handleMouseLeave] = useMouseInside(isOpen, onClose, undefined, IS_SINGLE_COLUMN_LAYOUT);
|
const [handleMouseEnter, handleMouseLeave] = useMouseInside(isOpen, onClose, undefined, IS_SINGLE_COLUMN_LAYOUT);
|
||||||
|
|
||||||
const handleClick = useCallback((botCommand: ApiBotCommand) => {
|
const handleClick = useCallback((botCommand: ApiBotCommand) => {
|
||||||
@ -57,7 +55,4 @@ const BotCommandMenu: FC<OwnProps & DispatchProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(withGlobal<OwnProps>(
|
export default memo(BotCommandMenu);
|
||||||
undefined,
|
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['sendBotCommand']),
|
|
||||||
)(BotCommandMenu));
|
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useCallback, useEffect, useRef, memo,
|
FC, useCallback, useEffect, useRef, memo,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../../lib/teact/teactn';
|
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
|
||||||
|
|
||||||
import { ApiBotCommand, ApiUser } from '../../../api/types';
|
import { ApiBotCommand, ApiUser } from '../../../api/types';
|
||||||
import { GlobalActions } from '../../../global/types';
|
|
||||||
|
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import setTooltipItemVisible from '../../../util/setTooltipItemVisible';
|
import setTooltipItemVisible from '../../../util/setTooltipItemVisible';
|
||||||
import useShowTransition from '../../../hooks/useShowTransition';
|
import useShowTransition from '../../../hooks/useShowTransition';
|
||||||
@ -29,17 +27,16 @@ type StateProps = {
|
|||||||
usersById: Record<string, ApiUser>;
|
usersById: Record<string, ApiUser>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'sendBotCommand'>;
|
const BotCommandTooltip: FC<OwnProps & StateProps> = ({
|
||||||
|
|
||||||
const BotCommandTooltip: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
usersById,
|
usersById,
|
||||||
isOpen,
|
isOpen,
|
||||||
withUsername,
|
withUsername,
|
||||||
botCommands,
|
botCommands,
|
||||||
onClick,
|
onClick,
|
||||||
onClose,
|
onClose,
|
||||||
sendBotCommand,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { sendBotCommand } = getDispatch();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const { shouldRender, transitionClassNames } = useShowTransition(isOpen, undefined, undefined, false);
|
const { shouldRender, transitionClassNames } = useShowTransition(isOpen, undefined, undefined, false);
|
||||||
@ -102,5 +99,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
(global): StateProps => ({
|
(global): StateProps => ({
|
||||||
usersById: global.users.byId,
|
usersById: global.users.byId,
|
||||||
}),
|
}),
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['sendBotCommand']),
|
|
||||||
)(BotCommandTooltip));
|
)(BotCommandTooltip));
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
import React, { FC, memo, useEffect } from '../../../lib/teact/teact';
|
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 { ApiMessage } from '../../../api/types';
|
||||||
|
|
||||||
import { IS_TOUCH_ENV } from '../../../util/environment';
|
import { IS_TOUCH_ENV } from '../../../util/environment';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import { selectChatMessage, selectCurrentMessageList } from '../../../modules/selectors';
|
import { selectChatMessage, selectCurrentMessageList } from '../../../modules/selectors';
|
||||||
import useMouseInside from '../../../hooks/useMouseInside';
|
import useMouseInside from '../../../hooks/useMouseInside';
|
||||||
import useFlag from '../../../hooks/useFlag';
|
import useFlag from '../../../hooks/useFlag';
|
||||||
@ -25,11 +23,11 @@ type StateProps = {
|
|||||||
message?: ApiMessage;
|
message?: ApiMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, ('clickInlineButton')>;
|
const BotKeyboardMenu: FC<OwnProps & StateProps> = ({
|
||||||
|
isOpen, message, onClose,
|
||||||
const BotKeyboardMenu: FC<OwnProps & StateProps & DispatchProps> = ({
|
|
||||||
isOpen, message, onClose, clickInlineButton,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { clickInlineButton } = getDispatch();
|
||||||
|
|
||||||
const [handleMouseEnter, handleMouseLeave] = useMouseInside(isOpen, onClose);
|
const [handleMouseEnter, handleMouseLeave] = useMouseInside(isOpen, onClose);
|
||||||
const { isKeyboardSingleUse } = message || {};
|
const { isKeyboardSingleUse } = message || {};
|
||||||
const [forceOpen, markForceOpen, unmarkForceOpen] = useFlag(true);
|
const [forceOpen, markForceOpen, unmarkForceOpen] = useFlag(true);
|
||||||
@ -87,7 +85,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
|
|
||||||
return { message: selectChatMessage(global, chatId, messageId) };
|
return { message: selectChatMessage(global, chatId, messageId) };
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'clickInlineButton',
|
|
||||||
]),
|
|
||||||
)(BotKeyboardMenu));
|
)(BotKeyboardMenu));
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState,
|
FC, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 {
|
import {
|
||||||
ApiAttachment,
|
ApiAttachment,
|
||||||
ApiBotInlineResult,
|
ApiBotInlineResult,
|
||||||
@ -52,7 +52,6 @@ import buildAttachment from './helpers/buildAttachment';
|
|||||||
import renderText from '../../common/helpers/renderText';
|
import renderText from '../../common/helpers/renderText';
|
||||||
import insertHtmlInSelection from '../../../util/insertHtmlInSelection';
|
import insertHtmlInSelection from '../../../util/insertHtmlInSelection';
|
||||||
import deleteLastCharacterOutsideSelection from '../../../util/deleteLastCharacterOutsideSelection';
|
import deleteLastCharacterOutsideSelection from '../../../util/deleteLastCharacterOutsideSelection';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import windowSize from '../../../util/windowSize';
|
import windowSize from '../../../util/windowSize';
|
||||||
import { isSelectionInsideInput } from './helpers/selection';
|
import { isSelectionInsideInput } from './helpers/selection';
|
||||||
@ -142,13 +141,6 @@ type StateProps =
|
|||||||
}
|
}
|
||||||
& Pick<GlobalState, 'connectionState'>;
|
& Pick<GlobalState, 'connectionState'>;
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'sendMessage' | 'editMessage' | 'saveDraft' | 'forwardMessages' |
|
|
||||||
'clearDraft' | 'showDialog' | 'setStickerSearchQuery' | 'setGifSearchQuery' |
|
|
||||||
'openPollModal' | 'closePollModal' | 'loadScheduledHistory' | 'openChat' |
|
|
||||||
'addRecentEmoji' | 'sendInlineBotResult'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
enum MainButtonState {
|
enum MainButtonState {
|
||||||
Send = 'send',
|
Send = 'send',
|
||||||
Record = 'record',
|
Record = 'record',
|
||||||
@ -167,7 +159,7 @@ const SENDING_ANIMATION_DURATION = 350;
|
|||||||
// eslint-disable-next-line max-len
|
// 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 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,
|
dropAreaState,
|
||||||
shouldSchedule,
|
shouldSchedule,
|
||||||
canScheduleUntilOnline,
|
canScheduleUntilOnline,
|
||||||
@ -205,21 +197,22 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
isInlineBotLoading,
|
isInlineBotLoading,
|
||||||
botCommands,
|
botCommands,
|
||||||
chatBotCommands,
|
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();
|
const lang = useLang();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
@ -428,8 +421,8 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
};
|
};
|
||||||
}, [chatId, resetComposer, stopRecordingVoiceRef]);
|
}, [chatId, resetComposer, stopRecordingVoiceRef]);
|
||||||
|
|
||||||
const handleEditComplete = useEditing(htmlRef, setHtml, editingMessage, resetComposer, openDeleteModal, editMessage);
|
const handleEditComplete = useEditing(htmlRef, setHtml, editingMessage, resetComposer, openDeleteModal);
|
||||||
useDraft(draft, chatId, threadId, html, htmlRef, setHtml, editingMessage, saveDraft, clearDraft);
|
useDraft(draft, chatId, threadId, html, htmlRef, setHtml, editingMessage);
|
||||||
useClipboardPaste(insertTextAndUpdateCursor, setAttachments, editingMessage);
|
useClipboardPaste(insertTextAndUpdateCursor, setAttachments, editingMessage);
|
||||||
|
|
||||||
const handleFileSelect = useCallback(async (files: File[], isQuick: boolean) => {
|
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,
|
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));
|
)(Composer));
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect,
|
FC, memo, useCallback, useEffect,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ApiChat, ApiMessage, ApiUser } from '../../../api/types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -19,7 +18,6 @@ import {
|
|||||||
selectEditingMessage,
|
selectEditingMessage,
|
||||||
} from '../../../modules/selectors';
|
} from '../../../modules/selectors';
|
||||||
import captureEscKeyListener from '../../../util/captureEscKeyListener';
|
import captureEscKeyListener from '../../../util/captureEscKeyListener';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import useAsyncRendering from '../../right/hooks/useAsyncRendering';
|
import useAsyncRendering from '../../right/hooks/useAsyncRendering';
|
||||||
import useShowTransition from '../../../hooks/useShowTransition';
|
import useShowTransition from '../../../hooks/useShowTransition';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
@ -39,22 +37,23 @@ type StateProps = {
|
|||||||
forwardedMessagesCount?: number;
|
forwardedMessagesCount?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'setReplyingToId' | 'setEditingId' | 'focusMessage' | 'exitForwardMode'>;
|
|
||||||
|
|
||||||
const FORWARD_RENDERING_DELAY = 300;
|
const FORWARD_RENDERING_DELAY = 300;
|
||||||
|
|
||||||
const ComposerEmbeddedMessage: FC<StateProps & DispatchProps> = ({
|
const ComposerEmbeddedMessage: FC<StateProps> = ({
|
||||||
replyingToId,
|
replyingToId,
|
||||||
editingId,
|
editingId,
|
||||||
message,
|
message,
|
||||||
sender,
|
sender,
|
||||||
shouldAnimate,
|
shouldAnimate,
|
||||||
forwardedMessagesCount,
|
forwardedMessagesCount,
|
||||||
setReplyingToId,
|
|
||||||
setEditingId,
|
|
||||||
focusMessage,
|
|
||||||
exitForwardMode,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
setReplyingToId,
|
||||||
|
setEditingId,
|
||||||
|
focusMessage,
|
||||||
|
exitForwardMode,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const isShown = Boolean(
|
const isShown = Boolean(
|
||||||
((replyingToId || editingId) && message)
|
((replyingToId || editingId) && message)
|
||||||
|| (sender && forwardedMessagesCount),
|
|| (sender && forwardedMessagesCount),
|
||||||
@ -166,10 +165,4 @@ export default memo(withGlobal(
|
|||||||
forwardedMessagesCount: isForwarding ? forwardMessageIds!.length : undefined,
|
forwardedMessagesCount: isForwarding ? forwardMessageIds!.length : undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'setReplyingToId',
|
|
||||||
'setEditingId',
|
|
||||||
'focusMessage',
|
|
||||||
'exitForwardMode',
|
|
||||||
]),
|
|
||||||
)(ComposerEmbeddedMessage));
|
)(ComposerEmbeddedMessage));
|
||||||
|
|||||||
@ -1,15 +1,13 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useEffect, memo, useRef,
|
FC, useEffect, memo, useRef,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ApiVideo } from '../../../api/types';
|
||||||
|
|
||||||
import { SLIDE_TRANSITION_DURATION } from '../../../config';
|
import { SLIDE_TRANSITION_DURATION } from '../../../config';
|
||||||
import { IS_TOUCH_ENV } from '../../../util/environment';
|
import { IS_TOUCH_ENV } from '../../../util/environment';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';
|
import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';
|
||||||
import useAsyncRendering from '../../right/hooks/useAsyncRendering';
|
import useAsyncRendering from '../../right/hooks/useAsyncRendering';
|
||||||
|
|
||||||
@ -29,18 +27,17 @@ type StateProps = {
|
|||||||
savedGifs?: ApiVideo[];
|
savedGifs?: ApiVideo[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadSavedGifs'>;
|
|
||||||
|
|
||||||
const INTERSECTION_DEBOUNCE = 300;
|
const INTERSECTION_DEBOUNCE = 300;
|
||||||
|
|
||||||
const GifPicker: FC<OwnProps & StateProps & DispatchProps> = ({
|
const GifPicker: FC<OwnProps & StateProps> = ({
|
||||||
className,
|
className,
|
||||||
loadAndPlay,
|
loadAndPlay,
|
||||||
canSendGifs,
|
canSendGifs,
|
||||||
savedGifs,
|
savedGifs,
|
||||||
onGifSelect,
|
onGifSelect,
|
||||||
loadSavedGifs,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { loadSavedGifs } = getDispatch();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
@ -88,5 +85,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
savedGifs: global.gifs.saved.gifs,
|
savedGifs: global.gifs.saved.gifs,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['loadSavedGifs']),
|
|
||||||
)(GifPicker));
|
)(GifPicker));
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useEffect, useRef,
|
FC, memo, useCallback, useEffect, useRef,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../../lib/teact/teactn';
|
|
||||||
|
|
||||||
import { GlobalActions } from '../../../global/types';
|
|
||||||
import { ApiBotInlineMediaResult, ApiBotInlineResult, ApiBotInlineSwitchPm } from '../../../api/types';
|
import { ApiBotInlineMediaResult, ApiBotInlineResult, ApiBotInlineSwitchPm } from '../../../api/types';
|
||||||
import { IAllowedAttachmentOptions } from '../../../modules/helpers';
|
import { IAllowedAttachmentOptions } from '../../../modules/helpers';
|
||||||
import { LoadMoreDirection } from '../../../types';
|
import { LoadMoreDirection } from '../../../types';
|
||||||
@ -13,7 +11,6 @@ import setTooltipItemVisible from '../../../util/setTooltipItemVisible';
|
|||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import useShowTransition from '../../../hooks/useShowTransition';
|
import useShowTransition from '../../../hooks/useShowTransition';
|
||||||
import { throttle } from '../../../util/schedulers';
|
import { throttle } from '../../../util/schedulers';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';
|
import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';
|
||||||
import usePrevious from '../../../hooks/usePrevious';
|
import usePrevious from '../../../hooks/usePrevious';
|
||||||
import { useKeyboardNavigation } from './hooks/useKeyboardNavigation';
|
import { useKeyboardNavigation } from './hooks/useKeyboardNavigation';
|
||||||
@ -26,6 +23,7 @@ import ListItem from '../../ui/ListItem';
|
|||||||
import InfiniteScroll from '../../ui/InfiniteScroll';
|
import InfiniteScroll from '../../ui/InfiniteScroll';
|
||||||
|
|
||||||
import './InlineBotTooltip.scss';
|
import './InlineBotTooltip.scss';
|
||||||
|
import { getDispatch } from '../../../lib/teact/teactn';
|
||||||
|
|
||||||
const INTERSECTION_DEBOUNCE_MS = 200;
|
const INTERSECTION_DEBOUNCE_MS = 200;
|
||||||
const runThrottled = throttle((cb) => cb(), 500, true);
|
const runThrottled = throttle((cb) => cb(), 500, true);
|
||||||
@ -42,9 +40,7 @@ export type OwnProps = {
|
|||||||
onClose: NoneToVoidFunction;
|
onClose: NoneToVoidFunction;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, ('startBot' | 'openChat' | 'sendInlineBotResult')>;
|
const InlineBotTooltip: FC<OwnProps> = ({
|
||||||
|
|
||||||
const InlineBotTooltip: FC<OwnProps & DispatchProps> = ({
|
|
||||||
isOpen,
|
isOpen,
|
||||||
botId,
|
botId,
|
||||||
isGallery,
|
isGallery,
|
||||||
@ -52,10 +48,13 @@ const InlineBotTooltip: FC<OwnProps & DispatchProps> = ({
|
|||||||
switchPm,
|
switchPm,
|
||||||
loadMore,
|
loadMore,
|
||||||
onClose,
|
onClose,
|
||||||
openChat,
|
|
||||||
startBot,
|
|
||||||
onSelectResult,
|
onSelectResult,
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
openChat,
|
||||||
|
startBot,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const { shouldRender, transitionClassNames } = useShowTransition(isOpen, undefined, undefined, false);
|
const { shouldRender, transitionClassNames } = useShowTransition(isOpen, undefined, undefined, false);
|
||||||
@ -196,9 +195,4 @@ const InlineBotTooltip: FC<OwnProps & DispatchProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(withGlobal<OwnProps>(
|
export default memo(InlineBotTooltip);
|
||||||
undefined,
|
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'startBot', 'openChat', 'sendInlineBotResult',
|
|
||||||
]),
|
|
||||||
)(InlineBotTooltip));
|
|
||||||
|
|||||||
@ -2,9 +2,8 @@ import { ChangeEvent } from 'react';
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useEffect, useRef, memo, useState, useCallback,
|
FC, useEffect, useRef, memo, useState, useCallback,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { IAnchorPosition, ISettings } from '../../../types';
|
||||||
|
|
||||||
import { EDITABLE_INPUT_ID } from '../../../config';
|
import { EDITABLE_INPUT_ID } from '../../../config';
|
||||||
@ -12,7 +11,6 @@ import { selectReplyingToId } from '../../../modules/selectors';
|
|||||||
import { debounce } from '../../../util/schedulers';
|
import { debounce } from '../../../util/schedulers';
|
||||||
import focusEditableElement from '../../../util/focusEditableElement';
|
import focusEditableElement from '../../../util/focusEditableElement';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import {
|
import {
|
||||||
IS_ANDROID, IS_EMOJI_SUPPORTED, IS_IOS, IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV,
|
IS_ANDROID, IS_EMOJI_SUPPORTED, IS_IOS, IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV,
|
||||||
} from '../../../util/environment';
|
} from '../../../util/environment';
|
||||||
@ -56,8 +54,6 @@ type StateProps = {
|
|||||||
messageSendKeyCombo?: ISettings['messageSendKeyCombo'];
|
messageSendKeyCombo?: ISettings['messageSendKeyCombo'];
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'editLastMessage' | 'replyToNextMessage'>;
|
|
||||||
|
|
||||||
const MAX_INPUT_HEIGHT = IS_SINGLE_COLUMN_LAYOUT ? 256 : 416;
|
const MAX_INPUT_HEIGHT = IS_SINGLE_COLUMN_LAYOUT ? 256 : 416;
|
||||||
const TAB_INDEX_PRIORITY_TIMEOUT = 2000;
|
const TAB_INDEX_PRIORITY_TIMEOUT = 2000;
|
||||||
const TEXT_FORMATTER_SAFE_AREA_PX = 90;
|
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,
|
id,
|
||||||
chatId,
|
chatId,
|
||||||
isAttachmentModalInput,
|
isAttachmentModalInput,
|
||||||
@ -94,9 +90,12 @@ const MessageInput: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
replyingToId,
|
replyingToId,
|
||||||
noTabCapture,
|
noTabCapture,
|
||||||
messageSendKeyCombo,
|
messageSendKeyCombo,
|
||||||
editLastMessage,
|
|
||||||
replyToNextMessage,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
editLastMessage,
|
||||||
|
replyToNextMessage,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const inputRef = useRef<HTMLDivElement>(null);
|
const inputRef = useRef<HTMLDivElement>(null);
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
@ -420,5 +419,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
noTabCapture: global.isPollModalOpen || global.payment.isPaymentModalOpen,
|
noTabCapture: global.isPollModalOpen || global.payment.isPaymentModalOpen,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['editLastMessage', 'replyToNextMessage']),
|
|
||||||
)(MessageInput));
|
)(MessageInput));
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, useState, useEffect, memo, useRef, useMemo, useCallback,
|
FC, useState, useEffect, memo, useRef, useMemo, useCallback,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ApiStickerSet, ApiSticker } from '../../../api/types';
|
||||||
import { StickerSetOrRecent } from '../../../types';
|
import { StickerSetOrRecent } from '../../../types';
|
||||||
|
|
||||||
@ -12,7 +11,6 @@ import { IS_TOUCH_ENV } from '../../../util/environment';
|
|||||||
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
||||||
import fastSmoothScroll from '../../../util/fastSmoothScroll';
|
import fastSmoothScroll from '../../../util/fastSmoothScroll';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import fastSmoothScrollHorizontal from '../../../util/fastSmoothScrollHorizontal';
|
import fastSmoothScrollHorizontal from '../../../util/fastSmoothScrollHorizontal';
|
||||||
import useAsyncRendering from '../../right/hooks/useAsyncRendering';
|
import useAsyncRendering from '../../right/hooks/useAsyncRendering';
|
||||||
import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';
|
import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';
|
||||||
@ -43,18 +41,13 @@ type StateProps = {
|
|||||||
shouldPlay?: boolean;
|
shouldPlay?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
|
||||||
'loadStickerSets' | 'loadRecentStickers' | 'loadFavoriteStickers' |
|
|
||||||
'addRecentSticker' | 'loadAddedStickers' | 'unfaveSticker'
|
|
||||||
)>;
|
|
||||||
|
|
||||||
const SMOOTH_SCROLL_DISTANCE = 500;
|
const SMOOTH_SCROLL_DISTANCE = 500;
|
||||||
const HEADER_BUTTON_WIDTH = 52; // px (including margin)
|
const HEADER_BUTTON_WIDTH = 52; // px (including margin)
|
||||||
const STICKER_INTERSECTION_THROTTLE = 200;
|
const STICKER_INTERSECTION_THROTTLE = 200;
|
||||||
|
|
||||||
const stickerSetIntersections: boolean[] = [];
|
const stickerSetIntersections: boolean[] = [];
|
||||||
|
|
||||||
const StickerPicker: FC<OwnProps & StateProps & DispatchProps> = ({
|
const StickerPicker: FC<OwnProps & StateProps> = ({
|
||||||
className,
|
className,
|
||||||
loadAndPlay,
|
loadAndPlay,
|
||||||
canSendStickers,
|
canSendStickers,
|
||||||
@ -64,13 +57,16 @@ const StickerPicker: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
stickerSetsById,
|
stickerSetsById,
|
||||||
shouldPlay,
|
shouldPlay,
|
||||||
onStickerSelect,
|
onStickerSelect,
|
||||||
loadStickerSets,
|
|
||||||
loadRecentStickers,
|
|
||||||
loadFavoriteStickers,
|
|
||||||
loadAddedStickers,
|
|
||||||
addRecentSticker,
|
|
||||||
unfaveSticker,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadStickerSets,
|
||||||
|
loadRecentStickers,
|
||||||
|
loadFavoriteStickers,
|
||||||
|
loadAddedStickers,
|
||||||
|
addRecentSticker,
|
||||||
|
unfaveSticker,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
@ -296,12 +292,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
shouldPlay: global.settings.byKey.shouldLoopStickers,
|
shouldPlay: global.settings.byKey.shouldLoopStickers,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'loadStickerSets',
|
|
||||||
'loadRecentStickers',
|
|
||||||
'loadFavoriteStickers',
|
|
||||||
'loadAddedStickers',
|
|
||||||
'addRecentSticker',
|
|
||||||
'unfaveSticker',
|
|
||||||
]),
|
|
||||||
)(StickerPicker));
|
)(StickerPicker));
|
||||||
|
|||||||
@ -1,16 +1,14 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useEffect, useRef,
|
FC, memo, useEffect, useRef,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
import { withGlobal } from '../../../lib/teact/teactn';
|
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
|
||||||
|
|
||||||
import { ApiSticker } from '../../../api/types';
|
import { ApiSticker } from '../../../api/types';
|
||||||
import { GlobalActions } from '../../../global/types';
|
|
||||||
|
|
||||||
import { STICKER_SIZE_PICKER } from '../../../config';
|
import { STICKER_SIZE_PICKER } from '../../../config';
|
||||||
import { IS_TOUCH_ENV } from '../../../util/environment';
|
import { IS_TOUCH_ENV } from '../../../util/environment';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import captureEscKeyListener from '../../../util/captureEscKeyListener';
|
import captureEscKeyListener from '../../../util/captureEscKeyListener';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';
|
import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';
|
||||||
import useShowTransition from '../../../hooks/useShowTransition';
|
import useShowTransition from '../../../hooks/useShowTransition';
|
||||||
import usePrevious from '../../../hooks/usePrevious';
|
import usePrevious from '../../../hooks/usePrevious';
|
||||||
@ -29,16 +27,15 @@ type StateProps = {
|
|||||||
stickers?: ApiSticker[];
|
stickers?: ApiSticker[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'clearStickersForEmoji'>;
|
|
||||||
|
|
||||||
const INTERSECTION_THROTTLE = 200;
|
const INTERSECTION_THROTTLE = 200;
|
||||||
|
|
||||||
const StickerTooltip: FC<OwnProps & StateProps & DispatchProps> = ({
|
const StickerTooltip: FC<OwnProps & StateProps> = ({
|
||||||
isOpen,
|
isOpen,
|
||||||
onStickerSelect,
|
onStickerSelect,
|
||||||
stickers,
|
stickers,
|
||||||
clearStickersForEmoji,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const { clearStickersForEmoji } = getDispatch();
|
||||||
|
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const { shouldRender, transitionClassNames } = useShowTransition(isOpen, undefined, undefined, false);
|
const { shouldRender, transitionClassNames } = useShowTransition(isOpen, undefined, undefined, false);
|
||||||
@ -96,5 +93,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
|
|
||||||
return { stickers };
|
return { stickers };
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['clearStickersForEmoji']),
|
|
||||||
)(StickerTooltip));
|
)(StickerTooltip));
|
||||||
|
|||||||
@ -1,15 +1,13 @@
|
|||||||
import React, {
|
import React, {
|
||||||
FC, memo, useEffect, useMemo,
|
FC, memo, useEffect, useMemo,
|
||||||
} from '../../../lib/teact/teact';
|
} 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 { ApiMessage, ApiMessageEntityTypes, ApiWebPage } from '../../../api/types';
|
||||||
import { ISettings } from '../../../types';
|
import { ISettings } from '../../../types';
|
||||||
|
|
||||||
import { RE_LINK_TEMPLATE } from '../../../config';
|
import { RE_LINK_TEMPLATE } from '../../../config';
|
||||||
import { selectNoWebPage, selectTheme } from '../../../modules/selectors';
|
import { selectNoWebPage, selectTheme } from '../../../modules/selectors';
|
||||||
import { pick } from '../../../util/iteratees';
|
|
||||||
import parseMessageInput from '../../../util/parseMessageInput';
|
import parseMessageInput from '../../../util/parseMessageInput';
|
||||||
import useOnChange from '../../../hooks/useOnChange';
|
import useOnChange from '../../../hooks/useOnChange';
|
||||||
import useShowTransition from '../../../hooks/useShowTransition';
|
import useShowTransition from '../../../hooks/useShowTransition';
|
||||||
@ -33,11 +31,10 @@ type StateProps = {
|
|||||||
noWebPage?: boolean;
|
noWebPage?: boolean;
|
||||||
theme: ISettings['theme'];
|
theme: ISettings['theme'];
|
||||||
};
|
};
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadWebPagePreview' | 'clearWebPagePreview' | 'toggleMessageWebPage'>;
|
|
||||||
|
|
||||||
const RE_LINK = new RegExp(RE_LINK_TEMPLATE, 'i');
|
const RE_LINK = new RegExp(RE_LINK_TEMPLATE, 'i');
|
||||||
|
|
||||||
const WebPagePreview: FC<OwnProps & StateProps & DispatchProps> = ({
|
const WebPagePreview: FC<OwnProps & StateProps> = ({
|
||||||
chatId,
|
chatId,
|
||||||
threadId,
|
threadId,
|
||||||
messageText,
|
messageText,
|
||||||
@ -45,10 +42,13 @@ const WebPagePreview: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
webPagePreview,
|
webPagePreview,
|
||||||
noWebPage,
|
noWebPage,
|
||||||
theme,
|
theme,
|
||||||
loadWebPagePreview,
|
|
||||||
clearWebPagePreview,
|
|
||||||
toggleMessageWebPage,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const {
|
||||||
|
loadWebPagePreview,
|
||||||
|
clearWebPagePreview,
|
||||||
|
toggleMessageWebPage,
|
||||||
|
} = getDispatch();
|
||||||
|
|
||||||
const link = useMemo(() => {
|
const link = useMemo(() => {
|
||||||
const { text, entities } = parseMessageInput(messageText);
|
const { text, entities } = parseMessageInput(messageText);
|
||||||
|
|
||||||
@ -121,7 +121,4 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
noWebPage,
|
noWebPage,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
|
||||||
'loadWebPagePreview', 'clearWebPagePreview', 'toggleMessageWebPage',
|
|
||||||
]),
|
|
||||||
)(WebPagePreview));
|
)(WebPagePreview));
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useCallback, useEffect, useMemo } from '../../../../lib/teact/teact';
|
import { useCallback, useEffect, useMemo } from '../../../../lib/teact/teact';
|
||||||
|
import { getDispatch } from '../../../../lib/teact/teactn';
|
||||||
|
|
||||||
import { ApiFormattedText, ApiMessage } from '../../../../api/types';
|
import { ApiFormattedText, ApiMessage } from '../../../../api/types';
|
||||||
import { GlobalActions } from '../../../../global/types';
|
|
||||||
|
|
||||||
import { DRAFT_DEBOUNCE, EDITABLE_INPUT_ID } from '../../../../config';
|
import { DRAFT_DEBOUNCE, EDITABLE_INPUT_ID } from '../../../../config';
|
||||||
import usePrevious from '../../../../hooks/usePrevious';
|
import usePrevious from '../../../../hooks/usePrevious';
|
||||||
@ -25,9 +25,9 @@ export default (
|
|||||||
htmlRef: { current: string },
|
htmlRef: { current: string },
|
||||||
setHtml: (html: string) => void,
|
setHtml: (html: string) => void,
|
||||||
editedMessage: ApiMessage | undefined,
|
editedMessage: ApiMessage | undefined,
|
||||||
saveDraft: GlobalActions['saveDraft'],
|
|
||||||
clearDraft: GlobalActions['clearDraft'],
|
|
||||||
) => {
|
) => {
|
||||||
|
const { saveDraft, clearDraft } = getDispatch();
|
||||||
|
|
||||||
const updateDraft = useCallback((draftChatId: string, draftThreadId: number) => {
|
const updateDraft = useCallback((draftChatId: string, draftThreadId: number) => {
|
||||||
if (htmlRef.current.length && !editedMessage) {
|
if (htmlRef.current.length && !editedMessage) {
|
||||||
saveDraft({ chatId: draftChatId, threadId: draftThreadId, draft: parseMessageInput(htmlRef.current!) });
|
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
Loading…
x
Reference in New Issue
Block a user