[Refactoring] Fix TS and ESLint errors after updating packages (#1386)

This commit is contained in:
Alexander Zinchuk 2021-08-16 14:21:33 +03:00
parent 714148fdf4
commit d7ca790f0a
67 changed files with 130 additions and 154 deletions

1
.eslintignore Normal file
View File

@ -0,0 +1 @@
dev

View File

@ -42,12 +42,15 @@
"import/no-webpack-loader-syntax": "off",
"react/prop-types": "off",
"react/jsx-one-expression-per-line": "off",
"react/button-has-type": "off",
"react/require-default-props": "off",
// Teact feature
"react/style-prop-object": "off",
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/no-static-element-interactions": "off",
"jsx-a11y/label-has-associated-control": "off",
"jsx-a11y/anchor-is-valid": "off",
"jsx-a11y/no-noninteractive-element-to-interactive-role": "off",
"no-async-without-await/no-async-without-await": 1,
"@typescript-eslint/no-use-before-define": [
"error",
@ -57,9 +60,13 @@
],
"@typescript-eslint/camelcase": "off",
"@typescript-eslint/member-delimiter-style": "error",
"@typescript-eslint/no-throw-literal": "off",
"teactn/prefer-separate-component-file": "off"
},
"settings": {
"import/resolver": "webpack"
},
"parserOptions": {
"project": "./tsconfig.json"
}
}

4
.husky/pre-commit Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx tsc && npx lint-staged

82
package-lock.json generated
View File

@ -4060,15 +4060,15 @@
}
},
"@jest/types": {
"version": "26.6.2",
"resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
"integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
"version": "27.0.6",
"resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
"integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
"@types/istanbul-reports": "^3.0.0",
"@types/node": "*",
"@types/yargs": "^15.0.0",
"@types/yargs": "^16.0.0",
"chalk": "^4.0.0"
},
"dependencies": {
@ -4478,13 +4478,13 @@
}
},
"@types/jest": {
"version": "27.0.0",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.0.tgz",
"integrity": "sha512-IlpQZVpxufe+3qPaAqEoSPHVSxnJh1cf0BqqWHJeKiAUbwnHdmNzjP3ZCWSZSTbmAGXQPNk9QmM3Bif0pR54rg==",
"version": "27.0.1",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.1.tgz",
"integrity": "sha512-HTLpVXHrY69556ozYkcq47TtQJXpcWAWfkoqz+ZGz2JnmZhzlRjprCIyFnetSy8gpDWwTTGBcRVv1J1I1vBrHw==",
"dev": true,
"requires": {
"jest-diff": "^26.0.0",
"pretty-format": "^26.0.0"
"jest-diff": "^27.0.0",
"pretty-format": "^27.0.0"
}
},
"@types/json-schema": {
@ -4583,9 +4583,9 @@
}
},
"@types/yargs": {
"version": "15.0.14",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz",
"integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==",
"version": "16.0.4",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
"integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@ -7121,9 +7121,9 @@
"dev": true
},
"diff-sequences": {
"version": "26.6.2",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz",
"integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==",
"version": "27.0.6",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz",
"integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==",
"dev": true
},
"dir-glob": {
@ -11580,15 +11580,15 @@
}
},
"jest-diff": {
"version": "26.6.2",
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz",
"integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==",
"version": "27.0.6",
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.6.tgz",
"integrity": "sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
"diff-sequences": "^26.6.2",
"jest-get-type": "^26.3.0",
"pretty-format": "^26.6.2"
"diff-sequences": "^27.0.6",
"jest-get-type": "^27.0.6",
"pretty-format": "^27.0.6"
},
"dependencies": {
"ansi-styles": {
@ -11951,9 +11951,9 @@
}
},
"jest-get-type": {
"version": "26.3.0",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
"integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
"version": "27.0.6",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
"integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
"dev": true
},
"jest-haste-map": {
@ -16230,14 +16230,14 @@
}
},
"pretty-format": {
"version": "26.6.2",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
"integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
"version": "27.0.6",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
"integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
"dev": true,
"requires": {
"@jest/types": "^26.6.2",
"@jest/types": "^27.0.6",
"ansi-regex": "^5.0.0",
"ansi-styles": "^4.0.0",
"ansi-styles": "^5.0.0",
"react-is": "^17.0.1"
},
"dependencies": {
@ -16248,27 +16248,9 @@
"dev": true
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"dev": true
},
"react-is": {

View File

@ -44,7 +44,7 @@
"@types/croppie": "^2.6.1",
"@types/css-font-loading-module": "0.0.6",
"@types/dom-mediacapture-record": "^1.0.10",
"@types/jest": "^27.0.0",
"@types/jest": "^27.0.1",
"@types/react": "^17.0.17",
"@types/react-dom": "^17.0.9",
"@types/resize-observer-browser": "^0.1.6",

View File

@ -56,9 +56,15 @@ declare module 'pako/dist/pako_inflate' {
type WindowWithPerf = typeof window & { perf: AnyLiteral };
interface TEncodedImage {
result: Uint8ClampedArray;
width: number;
height: number;
}
interface IWebpWorker extends Worker {
wasmReady?: boolean;
requests: Map<string, (value?: PromiseLike<TEncodedImage>) => void>;
requests: Map<string, (value: PromiseLike<TEncodedImage>) => void>;
}
interface Window {

View File

@ -463,7 +463,6 @@ function buildPollFromMedia(media: GramJs.TypeMessageMedia): ApiPoll | undefined
return buildPoll(media.poll, media.results);
}
function buildInvoiceFromMedia(media: GramJs.TypeMessageMedia): ApiInvoice | undefined {
if (!(media instanceof GramJs.MessageMediaInvoice)) {
return undefined;

View File

@ -75,7 +75,6 @@ export async function fetchChats({
return undefined;
}
if (resultPinned) {
updateLocalDb(resultPinned);
}

View File

@ -185,7 +185,7 @@ export async function invokeRequest<T extends GramJs.AnyRequest>(
let updatesContainer;
if (result instanceof GramJs.Updates || result instanceof GramJs.UpdatesCombined) {
updatesContainer = result;
} else if ('updates' in result && (
} else if ('updates' in (result as ResultWithUpdates) && (
(result as ResultWithUpdates).updates instanceof GramJs.Updates
|| (result as ResultWithUpdates).updates instanceof GramJs.UpdatesCombined
)) {

View File

@ -582,6 +582,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
typingStatus: buildChatTypingStatus(update, serverTimeOffset),
});
} else if (update instanceof GramJs.UpdateChannel) {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { _entities } = update;
if (!_entities) {
return;
@ -690,6 +691,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
user: { phoneNumber: phone },
});
} else if (update instanceof GramJs.UpdatePeerSettings) {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { _entities } = update;
if (!_entities) {
return;

View File

@ -4,7 +4,7 @@ import {
export type ApiInlineResultType = (
'article' | 'audio' | 'contact' | 'document' | 'game' | 'gif' | 'location' | 'mpeg4_gif' |
'photo' | 'sticker'| 'venue' | 'video' | 'voice'
'photo' | 'sticker' | 'venue' | 'video' | 'voice'
);
export interface ApiWebDocument {

View File

@ -365,7 +365,7 @@ export type ApiUpdateNotifyExceptions = {
'@type': 'updateNotifyExceptions';
} & ApiNotifyException;
export type updateTwoFaStateWaitCode = {
export type ApiUpdateTwoFaStateWaitCode = {
'@type': 'updateTwoFaStateWaitCode';
length: number;
};
@ -393,7 +393,6 @@ export type ApiUpdateServerTimeOffset = {
serverTimeOffset: number;
};
export type ApiUpdate = (
ApiUpdateReady | ApiUpdateSession |
ApiUpdateAuthorizationState | ApiUpdateAuthorizationError | ApiUpdateConnectionState | ApiUpdateCurrentUser |
@ -409,7 +408,7 @@ export type ApiUpdate = (
ApiUpdateFavoriteStickers | ApiUpdateStickerSet |
ApiUpdateNewScheduledMessage | ApiUpdateScheduledMessageSendSucceeded | ApiUpdateScheduledMessage |
ApiUpdateDeleteScheduledMessages | ApiUpdateResetMessages |
ApiUpdateTwoFaError | updateTwoFaStateWaitCode |
ApiUpdateTwoFaError | ApiUpdateTwoFaStateWaitCode |
ApiUpdateNotifySettings | ApiUpdateNotifyExceptions | ApiUpdatePeerBlocked | ApiUpdatePrivacy |
ApiUpdateServerTimeOffset | ApiUpdateShowInvite
);

View File

@ -217,8 +217,8 @@ const Audio: FC<OwnProps> = ({
const seekHandlers = { handleStartSeek, handleSeek, handleStopSeek };
const isOwn = isOwnMessage(message);
const renderedWaveform = useMemo(
() => voice && renderWaveform(voice, playProgress, isOwn, seekHandlers, theme),
[voice, playProgress, isOwn, seekHandlers, theme],
() => voice && renderWaveform(voice, playProgress, isOwn, { handleStartSeek, handleSeek, handleStopSeek }, theme),
[voice, playProgress, isOwn, handleStartSeek, handleSeek, handleStopSeek, theme],
);
const fullClassName = buildClassName(

View File

@ -51,7 +51,7 @@ const ReportMessageModal: FC<OwnProps & DispatchProps> = ({
const lang = useLang();
const REPORT_OPTIONS: {value: ApiReportReason; label: string}[] = [
const REPORT_OPTIONS: { value: ApiReportReason; label: string }[] = [
{ value: 'spam', label: lang('lng_report_reason_spam') },
{ value: 'violence', label: lang('lng_report_reason_violence') },
{ value: 'pornography', label: lang('lng_report_reason_pornography') },

View File

@ -33,13 +33,13 @@ type DispatchProps = Pick<GlobalActions, (
enum ContentType {
Main,
// eslint-disable-next-line no-shadow
// eslint-disable-next-line @typescript-eslint/no-shadow
Settings,
Archived,
// eslint-disable-next-line no-shadow
NewGroup,
// eslint-disable-next-line no-shadow
NewChannel
NewChannel,
}
const RENDER_COUNT = Object.keys(ContentType).length / 2;

View File

@ -49,7 +49,7 @@ type DispatchProps = Pick<GlobalActions, 'loadMoreChats' | 'preloadTopChatMessag
enum FolderTypeToListType {
'all' = 'active',
'archived' = 'archived'
'archived' = 'archived',
}
const ChatList: FC<OwnProps & StateProps & DispatchProps> = ({

View File

@ -130,7 +130,6 @@ const SettingsPrivacyBlockedUsers: FC<OwnProps & StateProps & DispatchProps> = (
);
};
export default memo(withGlobal<OwnProps>(
(global): StateProps => {
const {

View File

@ -129,7 +129,6 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps & Dispatc
useHistoryBack(isActive, onReset, onScreenSelect, screen);
return (
<div className="NewChat-inner step-1">
<Picker

View File

@ -71,6 +71,7 @@ const NOTIFICATION_INTERVAL = 1000;
let notificationInterval: number | undefined;
// eslint-disable-next-line @typescript-eslint/naming-convention
let DEBUG_isLogged = false;
const Main: FC<StateProps & DispatchProps> = ({
@ -135,7 +136,6 @@ const Main: FC<StateProps & DispatchProps> = ({
transitionClassNames: rightColumnTransitionClassNames,
} = useShowTransition(isRightColumnShown, undefined, true, undefined, shouldSkipHistoryAnimations);
const className = buildClassName(
middleColumnTransitionClassNames.replace(/([\w-]+)/g, 'middle-column-$1'),
rightColumnTransitionClassNames.replace(/([\w-]+)/g, 'right-column-$1'),

View File

@ -91,7 +91,6 @@ const ContactGreeting: FC<OwnProps & StateProps & DispatchProps> = ({
);
};
export default memo(withGlobal<OwnProps>(
(global, { userId }): StateProps => {
const { stickers } = global.stickers.greeting;

View File

@ -300,7 +300,7 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
useLayoutEffectWithPrevDeps(([
prevMessageIds, prevIsViewportNewest, prevContainerHeight,
]: [
typeof messageIds, typeof isViewportNewest, typeof containerHeight
typeof messageIds, typeof isViewportNewest, typeof containerHeight,
]) => {
const container = containerRef.current!;
listItemElementsRef.current = Array.from(container.querySelectorAll<HTMLDivElement>('.message-list-item'));

View File

@ -239,7 +239,6 @@ const MiddleColumn: FC<StateProps & DispatchProps> = ({
!isSelectModeActive && 'shown',
);
const messageSendingRestrictionReason = getMessageSendingRestrictionReason(
lang, currentUserBannedRights, defaultBannedRights,
);

View File

@ -75,5 +75,4 @@ function renderGroup(lang: LangFn) {
);
}
export default memo(NoMessages);

View File

@ -110,7 +110,6 @@ const InlineBotTooltip: FC<OwnProps & DispatchProps> = ({
}
}, [loadMore]);
useEffect(() => (isOpen ? captureKeyboardListeners({
onEsc: onClose,
onUp: (e: KeyboardEvent) => handleArrowKey(-1, e),
@ -123,7 +122,6 @@ const InlineBotTooltip: FC<OwnProps & DispatchProps> = ({
sendBotCommand({ chatId: botId, command: `/start ${switchPm!.startParam}` });
}, [botId, openChat, sendBotCommand, switchPm]);
const prevInlineBotResults = usePrevious(
inlineBotResults && inlineBotResults.length
? inlineBotResults

View File

@ -51,7 +51,6 @@ const CommentButton: FC<OwnProps & StateProps & DispatchProps> = ({
openChat({ id: chatId, threadId });
}, [openChat, chatId, threadId]);
useEffect(() => {
if (shouldRequestThreadUpdate) {
requestThreadInfoUpdate({ chatId, threadId });

View File

@ -241,7 +241,6 @@ const Message: FC<OwnProps & StateProps & DispatchProps> = ({
const appendixRef = useRef<HTMLDivElement>(null);
const lang = useLang();
useOnIntersect(bottomMarkerRef, observeIntersectionForBottom);
const {

View File

@ -261,7 +261,6 @@ function layoutWithComplexLayouter({
return result;
}
function layoutTwo(params: ILayoutParams) {
const {
ratios,

View File

@ -205,7 +205,6 @@ const RightColumn: FC<StateProps & DispatchProps> = ({
}
}, [contentKey, chatId]);
useHistoryBack(isChatSelected && (contentKey === RightColumnContent.ChatInfo
|| contentKey === RightColumnContent.UserInfo || contentKey === RightColumnContent.Management
|| contentKey === RightColumnContent.AddingMembers),

View File

@ -139,7 +139,6 @@ const ManageChannel: FC<OwnProps & StateProps & DispatchProps> = ({
onScreenSelect(ManagementScreens.ChannelSubscribers);
}, [onScreenSelect]);
const handleDeleteChannel = useCallback(() => {
if (chat.isCreator) {
deleteChannel({ chatId: chat.id });

View File

@ -60,7 +60,7 @@ const ManageChatPrivacyType: FC<OwnProps & StateProps & DispatchProps> = ({
const [username, setUsername] = useState();
const [isRevokeConfirmDialogOpen, openRevokeConfirmDialog, closeRevokeConfirmDialog] = useFlag();
const canUpdate = (
const canUpdate = Boolean(
(privacyType === 'public' && username && isUsernameAvailable)
|| (privacyType === 'private' && isPublic)
);

View File

@ -333,7 +333,6 @@ const ManageGroupAdminRights: FC<OwnProps & StateProps & DispatchProps> = ({
);
};
export default memo(withGlobal<OwnProps>(
(global, { chatId, isPromotedByCurrentUser }): StateProps => {
const chat = selectChat(global, chatId)!;

View File

@ -259,7 +259,6 @@ const ManageGroupUserPermissions: FC<OwnProps & StateProps & DispatchProps> = ({
);
};
export default memo(withGlobal<OwnProps>(
(global, { chatId, isPromotedByCurrentUser }): StateProps => {
const chat = selectChat(global, chatId)!;

View File

@ -85,7 +85,6 @@ const ManageGroupUserPermissionsCreate: FC<OwnProps & StateProps> = ({
);
};
export default memo(withGlobal<OwnProps>(
(global, { chatId }): StateProps => {
const chat = selectChat(global, chatId);

View File

@ -25,21 +25,6 @@ type BOwnProps = Pick<GlobalState, 'authState'> & {
aValue: number;
};
const TestA: FC<AStateProps> = ({ aValue }) => {
// eslint-disable-next-line no-console
console.log('!!! A MOUNT ', { aValue });
return (
<div>
<h1>A</h1>
<div>
aValue = {aValue}
</div>
<TestBContainer aValue={aValue} />
</div>
);
};
const TestB: FC<BStateProps & BOwnProps> = ({ bValue, aValue, derivedAValue }) => {
// eslint-disable-next-line no-console
console.log('!!! B MOUNT ', { bValue, aValue, derivedAValue });
@ -65,7 +50,6 @@ const TestB: FC<BStateProps & BOwnProps> = ({ bValue, aValue, derivedAValue }) =
);
};
const TestBContainer = withGlobal<BOwnProps>(
(global, { aValue }): BStateProps => {
// eslint-disable-next-line no-console
@ -79,6 +63,21 @@ const TestBContainer = withGlobal<BOwnProps>(
},
)(TestB);
const TestA: FC<AStateProps> = ({ aValue }) => {
// eslint-disable-next-line no-console
console.log('!!! A MOUNT ', { aValue });
return (
<div>
<h1>A</h1>
<div>
aValue = {aValue}
</div>
<TestBContainer aValue={aValue} />
</div>
);
};
export default withGlobal(
(global): AStateProps => {
// @ts-ignore

View File

@ -54,11 +54,11 @@ const InfiniteScroll: FC<OwnProps> = ({
}
const stateRef = useRef<{
listItemElements: NodeListOf<HTMLDivElement>;
isScrollTopJustUpdated: boolean;
currentAnchor: HTMLDivElement | undefined;
currentAnchorTop: number;
}>({} as any);
listItemElements?: NodeListOf<HTMLDivElement>;
isScrollTopJustUpdated?: boolean;
currentAnchor?: HTMLDivElement | undefined;
currentAnchorTop?: number;
}>({});
const [loadMoreBackwards, loadMoreForwards] = useMemo(() => {
if (!onLoadMore) {
@ -105,7 +105,7 @@ const InfiniteScroll: FC<OwnProps> = ({
if (state.currentAnchor && Array.from(state.listItemElements).includes(state.currentAnchor)) {
const { scrollTop } = container;
const newAnchorTop = state.currentAnchor.getBoundingClientRect().top;
newScrollTop = scrollTop + (newAnchorTop - state.currentAnchorTop);
newScrollTop = scrollTop + (newAnchorTop - state.currentAnchorTop!);
} else {
const nextAnchor = state.listItemElements[0];
if (nextAnchor) {
@ -130,8 +130,9 @@ const InfiniteScroll: FC<OwnProps> = ({
const handleScroll = useCallback((e: UIEvent<HTMLDivElement>) => {
if (loadMoreForwards && loadMoreBackwards) {
const {
listItemElements, isScrollTopJustUpdated, currentAnchor, currentAnchorTop,
isScrollTopJustUpdated, currentAnchor, currentAnchorTop,
} = stateRef.current;
const listItemElements = stateRef.current.listItemElements!;
if (isScrollTopJustUpdated) {
stateRef.current.isScrollTopJustUpdated = false;

View File

@ -48,7 +48,7 @@ const RippleEffect: FC = () => {
return (
<div className="ripple-container" onMouseDown={handleMouseDown}>
{ripples.map(({ x, y, size }: Ripple) => (
{ripples.map(({ x, y, size }) => (
<span
// @ts-ignore
style={`left: ${x}px; top: ${y}px; width: ${size}px; height: ${size}px;`}

View File

@ -1,7 +1,6 @@
import { ChangeEvent, RefObject } from 'react';
import React, { FC, memo } from '../../lib/teact/teact';
import buildClassName from '../../util/buildClassName';
type OwnProps = {

View File

@ -99,7 +99,6 @@ export default function useHistoryBack(
state: currentState,
}, '');
indexRef.current = index;
if (shouldReplaceNext) {

View File

@ -1,12 +1,10 @@
import { ApiMediaFormat } from '../api/types';
import * as langProvider from '../util/langProvider';
import useForceUpdate from './useForceUpdate';
import useOnChange from './useOnChange';
export type LangFn = typeof langProvider.getTranslation;
export default <T extends ApiMediaFormat = ApiMediaFormat.BlobUrl>(): LangFn => {
export default (): LangFn => {
const forceUpdate = useForceUpdate();
useOnChange(() => {

View File

@ -15,7 +15,6 @@ export default (
// СSS class should be added in a separate tick to turn on CSS transition.
const [hasOpenClassName, setHasOpenClassName] = useState(isOpen && noOpenTransition);
if (isOpen) {
setIsClosed(false);
setHasOpenClassName(true);

View File

@ -208,7 +208,7 @@ async function signInUserWithQrCode(
}
})();
const updatePromise = new Promise((resolve) => {
const updatePromise = new Promise<void>((resolve) => {
client.addEventHandler((update: Api.TypeUpdate) => {
if (update instanceof Api.UpdateLoginToken) {
resolve();

View File

@ -27,7 +27,9 @@ const LOW_PRIORITY_MAX_FPS = 30;
const HIGH_PRIORITY_CACHE_MODULO = IS_SAFARI ? 2 : 4;
const LOW_PRIORITY_CACHE_MODULO = 0;
const workers = new Array(MAX_WORKERS).fill(undefined).map(() => new WorkerConnector(new Worker(new URL('./rlottie.worker.ts', import.meta.url))));
const workers = new Array(MAX_WORKERS).fill(undefined).map(
() => new WorkerConnector(new Worker(new URL('./rlottie.worker.ts', import.meta.url))),
);
let lastWorkerIndex = -1;
class RLottie {

View File

@ -12,7 +12,7 @@ declare const self: WorkerGlobalScope;
self.importScripts('rlottie-wasm.js');
let rLottieApi: Record<string, Function>;
const rLottieApiPromise = new Promise((resolve) => {
const rLottieApiPromise = new Promise<void>((resolve) => {
Module.onRuntimeInitialized = () => {
rLottieApi = {
init: Module.cwrap('lottie_init', '', []),

View File

@ -30,6 +30,7 @@ const MAPPED_ATTRIBUTES: { [k: string]: string } = {
const INDEX_KEY_PREFIX = '__indexKey#';
const headsByElement: Record<string, VirtualDomHead> = {};
// eslint-disable-next-line @typescript-eslint/naming-convention
let DEBUG_virtualTreeSize = 1;
function render($element?: VirtualElement, parentEl?: HTMLElement | null) {
@ -462,6 +463,7 @@ function updateAttribute(element: HTMLElement, key: string, oldValue: any, newVa
}
}
// eslint-disable-next-line @typescript-eslint/naming-convention
function DEBUG_addToVirtualTreeSize($current: VirtualRealElement | VirtualDomHead) {
DEBUG_virtualTreeSize += $current.children.length;

View File

@ -9,11 +9,12 @@ import { removeAllDelegatedListeners } from './dom-events';
export type Props = AnyLiteral;
export type FC<P extends Props = any> = (props: P) => any;
// eslint-disable-next-line @typescript-eslint/naming-convention
export type FC_withDebug =
FC
& {
DEBUG_contentComponentName?: string;
};
};
export enum VirtualElementTypesEnum {
Empty,
@ -243,6 +244,7 @@ function buildEmptyElement(): VirtualElementEmpty {
return { type: VirtualElementTypesEnum.Empty };
}
// eslint-disable-next-line @typescript-eslint/naming-convention
const DEBUG_components: AnyLiteral = {};
document.addEventListener('dblclick', () => {
@ -260,6 +262,7 @@ export function renderComponent(componentInstance: ComponentInstance) {
let newRenderedValue;
try {
// eslint-disable-next-line @typescript-eslint/naming-convention
let DEBUG_startAt: number | undefined;
if (DEBUG) {
const componentName = componentInstance.name;

View File

@ -78,6 +78,7 @@ function onDispatch(name: string, payload?: ActionPayload, noThrottle?: boolean)
}
function updateContainers() {
// eslint-disable-next-line @typescript-eslint/naming-convention
let DEBUG_startAt: number | undefined;
if (DEBUG) {
DEBUG_startAt = performance.now();

View File

@ -237,7 +237,7 @@ addReducer('joinChannel', (global, actions, payload) => {
addReducer('deleteChatUser', (global, actions, payload) => {
(async () => {
const { chatId, userId } : {chatId: number; userId: number} = payload!;
const { chatId, userId } : { chatId: number; userId: number } = payload!;
const chat = selectChat(global, chatId);
const user = selectUser(global, userId);
if (!chat || !user) {
@ -254,7 +254,7 @@ addReducer('deleteChatUser', (global, actions, payload) => {
addReducer('deleteChat', (global, actions, payload) => {
(async () => {
const { chatId } : {chatId: number } = payload!;
const { chatId } : { chatId: number } = payload!;
const chat = selectChat(global, chatId);
if (!chat) {
return;
@ -742,7 +742,6 @@ addReducer('unlinkDiscussionGroup', (global, actions, payload) => {
})();
});
addReducer('setActiveChatFolder', (global, actions, payload) => {
return {
...global,
@ -857,7 +856,6 @@ async function loadChats(listType: 'active' | 'archived', offsetId?: number, off
);
});
if (chatIds.length === 0 && !global.chats.isFullyLoaded[listType]) {
global = {
...global,

View File

@ -71,7 +71,6 @@ addReducer('getPaymentForm', (global, actions, payload) => {
void getPaymentForm(chat, messageId);
});
async function getPaymentForm(chat: ApiChat, messageId: number) {
const result = await callApi('getPaymentForm', { chat, messageId });
if (!result) {

View File

@ -203,7 +203,6 @@ addReducer('loadProfilePhotos', (global, actions, payload) => {
})();
});
addReducer('setUserSearchQuery', (global, actions, payload) => {
const { query } = payload!;

View File

@ -211,7 +211,6 @@ export function getChatSlowModeOptions(chat?: ApiChat) {
return chat.fullInfo.slowMode;
}
export function getChatOrder(chat: ApiChat) {
return Math.max(
chat.joinDate || 0,

View File

@ -14,7 +14,6 @@ type Target =
| 'viewerFull'
| 'download';
export function getMessageContent(message: ApiMessage) {
return message.content;
}

View File

@ -47,5 +47,5 @@ export function getStripeError(error: {
const { message: description, code, param } = error;
const { field, message } = param ? STRIPE_ERRORS[param] : STRIPE_ERRORS[code];
return { field, message, description};
return { field, message, description };
}

View File

@ -1,7 +1,6 @@
import { GlobalState } from '../../global/types';
import { InlineBotSettings } from '../../types';
export function replaceInlineBotSettings(
global: GlobalState, username: string, inlineBotSettings: InlineBotSettings | false,
): GlobalState {

View File

@ -228,7 +228,6 @@ export function deleteChatMessages(
}
});
global = replaceThreadParam(global, chatId, threadId, 'listedIds', listedIds);
global = replaceThreadParam(global, chatId, threadId, 'outlyingIds', outlyingIds);
global = replaceThreadParam(global, chatId, threadId, 'viewportIds', viewportIds);

View File

@ -68,7 +68,6 @@ export function updateUser(global: GlobalState, userId: number, userUpdate: Part
});
}
export function updateUsers(global: GlobalState, updatedById: Record<number, ApiUser>): GlobalState {
const updatedUsers = Object.keys(updatedById).map(Number).reduce<Record<number, ApiUser>>((acc, id) => {
const updatedUser = getUpdatedUser(global, id, updatedById[id]);

View File

@ -1,4 +1,3 @@
import { GlobalState } from '../../global/types';
export function selectPaymentChatId(global: GlobalState) {

View File

@ -4,7 +4,7 @@ declare const self: ServiceWorkerGlobalScope;
enum Boolean {
True = '1',
False = '0'
False = '0',
}
type PushData = {

View File

@ -278,7 +278,7 @@ export enum PaymentStep {
ShippingInfo,
Shipping,
PaymentInfo,
Checkout
Checkout,
}
export const UPLOADING_WALLPAPER_SLUG = 'UPLOADING_WALLPAPER_SLUG';

View File

@ -29,7 +29,6 @@ export default function fastSmoothScroll(
return;
}
if (getGlobal().settings.byKey.animationLevel === ANIMATION_LEVEL_MIN) {
forceDuration = 0;
}

View File

@ -83,7 +83,7 @@ export async function createPosterForVideo(url: string): Promise<string | undefi
return Promise.race([
pause(2000) as Promise<undefined>,
new Promise<string>((resolve, reject) => {
new Promise<string | undefined>((resolve, reject) => {
video.onseeked = () => {
if (!video.videoWidth || !video.videoHeight) {
resolve(undefined);

View File

@ -3,7 +3,7 @@ import { DEBUG } from '../config';
export enum Bundles {
Auth,
Main,
Extra
Extra,
}
interface ImportedBundles {

View File

@ -7,7 +7,9 @@ export async function oggToWav(opusData: Blob): Promise<Blob> {
return new Promise((resolve) => {
const typedArray = new Uint8Array(arrayBuffer);
let decoderWorker: Worker | undefined = new Worker(new URL('opus-recorder/dist/decoderWorker.min.js', import.meta.url));
let decoderWorker: Worker | undefined = new Worker(
new URL('opus-recorder/dist/decoderWorker.min.js', import.meta.url),
);
let wavWorker: Worker | undefined = new Worker(new URL('opus-recorder/dist/waveWorker.min.js', import.meta.url));
decoderWorker.onmessage = (e) => {

View File

@ -122,12 +122,12 @@ function runNow(fn: NoneToVoidFunction) {
fn();
}
export const pause = (ms: number) => new Promise((resolve) => {
export const pause = (ms: number) => new Promise<void>((resolve) => {
setTimeout(() => resolve(), ms);
});
export function rafPromise() {
return new Promise((resolve) => {
return new Promise<void>((resolve) => {
fastRaf(resolve);
});
}

View File

@ -3,8 +3,8 @@ import encoderPath from 'file-loader!opus-recorder/dist/encoderWorker.min';
export type Result = { blob: Blob; duration: number; waveform: number[] };
interface OpusRecorder extends Omit<MediaRecorder, 'start' | 'ondataavailable'> {
new(options: AnyLiteral): OpusRecorder;
interface IOpusRecorder extends Omit<MediaRecorder, 'start' | 'ondataavailable'> {
new(options: AnyLiteral): IOpusRecorder;
start(stream?: MediaStreamAudioSourceNode): void;
@ -19,9 +19,9 @@ const BLOB_PARAMS = { type: 'audio/ogg' };
const FFT_SIZE = 64;
const MIN_VOLUME = 0.1;
let opusRecorderPromise: Promise<{ default: OpusRecorder }>;
let OpusRecorder: OpusRecorder;
let mediaRecorder: OpusRecorder;
let opusRecorderPromise: Promise<{ default: IOpusRecorder }>;
let OpusRecorder: IOpusRecorder;
let mediaRecorder: IOpusRecorder;
export async function init() {
if (!opusRecorderPromise) {
@ -84,7 +84,7 @@ async function startMediaRecorder() {
await mediaRecorder.start();
}
function subscribeToAnalyzer(recorder: OpusRecorder, cb: Function) {
function subscribeToAnalyzer(recorder: IOpusRecorder, cb: Function) {
const source = recorder.sourceNode;
const analyser = source.context.createAnalyser();
analyser.fftSize = FFT_SIZE;

View File

@ -2,12 +2,6 @@ import { isWebpSupported } from './environment';
import { dataUriToBlob, blobToDataUri } from './files';
import { pause } from './schedulers';
type TEncodedImage = {
result: Uint8ClampedArray;
width: number;
height: number;
};
const WORKER_INITIALIZATION_TIMEOUT = 2000;
let canvas: HTMLCanvasElement;
@ -96,7 +90,10 @@ function handleLibWebpMessage(e: MessageEvent) {
function getDecodePromise(url: string, blob: Blob): Promise<TEncodedImage> {
return new Promise((resolve) => {
worker.requests = worker.requests || new Map();
if (!worker.requests) {
worker.requests = new Map();
}
worker.requests.set(url, resolve);
worker.postMessage({ id: url, blob });
});

View File

@ -31,7 +31,7 @@ export const forceWebsync = (authed: boolean) => {
if (canRedirect !== authed || ts + WEBSYNC_TIMEOUT <= currentTs) {
return Promise.all(WEBSYNC_URLS.map((url) => {
return new Promise((resolve, reject) => {
return new Promise<void>((resolve, reject) => {
const script = document.createElement('script');
const removeElement = () => !!document.body.removeChild(script);

View File

@ -21,6 +21,7 @@
"jsx": "react"
},
"include": [
"src"
"src",
"tests"
]
}