[dev] More stylistic eslint rules (#5961)
This commit is contained in:
parent
ee7f2e1c8c
commit
bd096e2a01
@ -16,6 +16,7 @@ import tseslint from 'typescript-eslint';
|
||||
export default tseslint.config(
|
||||
eslint.configs.recommended,
|
||||
tseslint.configs.recommendedTypeChecked,
|
||||
tseslint.configs.stylistic,
|
||||
reactPlugin.configs.flat.recommended,
|
||||
reactXPlugin.configs['recommended-type-checked'],
|
||||
jsxA11yPlugin.flatConfigs.recommended,
|
||||
@ -51,6 +52,20 @@ export default tseslint.config(
|
||||
rules: {
|
||||
'no-null/no-null': 'error',
|
||||
'no-console': 'error',
|
||||
'no-template-curly-in-string': 'error',
|
||||
'object-shorthand': 'error',
|
||||
curly: ['error', 'multi-line'],
|
||||
'no-implicit-coercion': [
|
||||
'error',
|
||||
{
|
||||
boolean: true,
|
||||
disallowTemplateShorthand: true,
|
||||
},
|
||||
],
|
||||
'no-prototype-builtins': 'off',
|
||||
'no-undef': 'off',
|
||||
'no-unused-vars': 'off',
|
||||
'@stylistic/multiline-ternary': 'off',
|
||||
'@stylistic/max-len': ['error', {
|
||||
code: 120,
|
||||
ignoreComments: true,
|
||||
@ -60,10 +75,6 @@ export default tseslint.config(
|
||||
SwitchCase: 1,
|
||||
flatTernaryExpressions: false,
|
||||
}],
|
||||
'@stylistic/multiline-ternary': 'off',
|
||||
'no-prototype-builtins': 'off',
|
||||
'no-undef': 'off',
|
||||
'no-unused-vars': 'off',
|
||||
'simple-import-sort/imports': [
|
||||
'error',
|
||||
{
|
||||
@ -115,7 +126,6 @@ export default tseslint.config(
|
||||
],
|
||||
},
|
||||
],
|
||||
// TypeScript type imports preference
|
||||
'@typescript-eslint/consistent-type-imports': [
|
||||
'error',
|
||||
{
|
||||
@ -130,6 +140,11 @@ export default tseslint.config(
|
||||
'@typescript-eslint/no-unsafe-return': 'off',
|
||||
'@typescript-eslint/no-floating-promises': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-inferrable-types': 'off',
|
||||
'@typescript-eslint/consistent-type-definitions': 'off',
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
'@typescript-eslint/prefer-for-of': 'off',
|
||||
'@typescript-eslint/array-type': 'off',
|
||||
'@typescript-eslint/no-misused-promises': [
|
||||
'error',
|
||||
{
|
||||
@ -169,6 +184,15 @@ export default tseslint.config(
|
||||
'react/no-unknown-property': 'off',
|
||||
'react/display-name': 'off',
|
||||
'react/jsx-key': 'off',
|
||||
'react/jsx-curly-spacing': [
|
||||
'error',
|
||||
{
|
||||
when: 'never',
|
||||
attributes: true,
|
||||
children: true,
|
||||
allowMultiline: true,
|
||||
},
|
||||
],
|
||||
'react-x/no-use-context': 'off',
|
||||
'react-x/no-context-provider': 'off',
|
||||
'react-x/no-array-index-key': 'off',
|
||||
|
||||
@ -3,7 +3,7 @@ import { devices, type PlaywrightTestConfig } from '@playwright/test';
|
||||
const config: PlaywrightTestConfig = {
|
||||
testDir: 'tests/playwright',
|
||||
timeout: process.env.CI ? 60 * 5 * 1000 : 30 * 1000,
|
||||
forbidOnly: !!process.env.CI,
|
||||
forbidOnly: Boolean(process.env.CI),
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
webServer: {
|
||||
command: 'npm run build:mocked && serve -l 1235 dist',
|
||||
|
||||
@ -86,7 +86,7 @@ import { handleGramJsUpdate, invokeRequest, uploadFile } from './client';
|
||||
type FullChatData = {
|
||||
fullInfo: ApiChatFullInfo;
|
||||
chats: ApiChat[];
|
||||
userStatusesById: { [userId: string]: ApiUserStatus };
|
||||
userStatusesById: Record<string, ApiUserStatus>;
|
||||
groupCall?: Partial<ApiGroupCall>;
|
||||
membersCount?: number;
|
||||
isForumAsMessages?: true;
|
||||
|
||||
@ -18,7 +18,7 @@ import * as cacheApi from '../../../util/cacheApi';
|
||||
import { getEntityTypeById } from '../gramjsBuilders';
|
||||
import localDb from '../localDb';
|
||||
|
||||
const MEDIA_ENTITY_TYPES: Set<EntityType> = new Set([
|
||||
const MEDIA_ENTITY_TYPES = new Set<EntityType>([
|
||||
'sticker', 'wallpaper', 'photo', 'webDocument', 'document',
|
||||
]);
|
||||
|
||||
|
||||
@ -2114,7 +2114,7 @@ export async function fetchOutboxReadDate({ chat, messageId }: { chat: ApiChat;
|
||||
const peer = buildInputPeer(id, accessHash);
|
||||
|
||||
const result = await invokeRequest(new GramJs.messages.GetOutboxReadDate({
|
||||
peer: peer,
|
||||
peer,
|
||||
msgId: messageId,
|
||||
}), { shouldThrow: true });
|
||||
|
||||
|
||||
@ -184,7 +184,7 @@ export function callApiLocal<T extends keyof Methods>(
|
||||
| (Api.VirtualClass<any> | undefined)[];
|
||||
type ForbiddenResponses =
|
||||
ForbiddenTypes
|
||||
| (AnyLiteral & { [k: string]: ForbiddenTypes });
|
||||
| (AnyLiteral & Record<string, ForbiddenTypes>);
|
||||
|
||||
// Unwrap all chained promises
|
||||
const response = await promise;
|
||||
@ -231,7 +231,7 @@ export function callApi<T extends keyof Methods>(fnName: T, ...args: MethodArgs<
|
||||
| (Api.VirtualClass<any> | undefined)[];
|
||||
type ForbiddenResponses =
|
||||
ForbiddenTypes
|
||||
| (AnyLiteral & { [k: string]: ForbiddenTypes });
|
||||
| (AnyLiteral & Record<string, ForbiddenTypes>);
|
||||
|
||||
// Unwrap all chained promises
|
||||
const response = await promise;
|
||||
@ -346,7 +346,7 @@ function makeRequestToMaster(message: {
|
||||
const requestState = { messageId } as RequestState;
|
||||
|
||||
// Re-wrap type because of `postMessage`
|
||||
const promise: Promise<MethodResponse<keyof Methods>> = new Promise((resolve, reject) => {
|
||||
const promise = new Promise<MethodResponse<keyof Methods>>((resolve, reject) => {
|
||||
Object.assign(requestState, { resolve, reject });
|
||||
});
|
||||
|
||||
@ -385,7 +385,7 @@ function makeRequest(message: OriginPayload) {
|
||||
const requestState = { messageId } as RequestState;
|
||||
|
||||
// Re-wrap type because of `postMessage`
|
||||
const promise: Promise<MethodResponse<keyof Methods>> = new Promise((resolve, reject) => {
|
||||
const promise = new Promise<MethodResponse<keyof Methods>>((resolve, reject) => {
|
||||
Object.assign(requestState, { resolve, reject });
|
||||
});
|
||||
|
||||
|
||||
@ -855,9 +855,7 @@ export type ApiReplyKeyboard = {
|
||||
keyboardPlaceholder?: string;
|
||||
isKeyboardSingleUse?: boolean;
|
||||
isKeyboardSelective?: boolean;
|
||||
} & {
|
||||
[K in 'inlineButtons' | 'keyboardButtons']?: ApiKeyboardButtons;
|
||||
};
|
||||
} & Partial<Record<'inlineButtons' | 'keyboardButtons', ApiKeyboardButtons>>;
|
||||
|
||||
export type ApiTranscription = {
|
||||
text: string;
|
||||
|
||||
@ -266,13 +266,11 @@ export interface ApiConfig {
|
||||
export type ApiPeerColorSet = string[];
|
||||
|
||||
export interface ApiPeerColors {
|
||||
general: {
|
||||
[key: number]: {
|
||||
isHidden?: true;
|
||||
colors?: ApiPeerColorSet;
|
||||
darkColors?: ApiPeerColorSet;
|
||||
};
|
||||
};
|
||||
general: Record<number, {
|
||||
isHidden?: true;
|
||||
colors?: ApiPeerColorSet;
|
||||
darkColors?: ApiPeerColorSet;
|
||||
}>;
|
||||
generalHash?: number;
|
||||
}
|
||||
|
||||
|
||||
@ -65,7 +65,6 @@ function AnimatedIconWithPreview(props: OwnProps) {
|
||||
onLoad={handlePreviewLoad}
|
||||
/>
|
||||
)}
|
||||
{ }
|
||||
<AnimatedIcon {...otherProps} onLoad={handleAnimationReady} />
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -364,7 +364,7 @@ const Audio: FC<OwnProps> = ({
|
||||
{withSeekline && (
|
||||
<div className="meta search-result" dir={isRtl ? 'rtl' : undefined}>
|
||||
<span className="duration with-seekline" dir="auto">
|
||||
{playProgress < 1 && `${formatMediaDuration(duration * playProgress, duration)}`}
|
||||
{playProgress < 1 && formatMediaDuration(duration * playProgress, duration)}
|
||||
</span>
|
||||
{renderSeekline(playProgress, bufferedRanges, seekerRef)}
|
||||
</div>
|
||||
|
||||
@ -312,7 +312,7 @@ const CalendarModal: FC<OwnProps> = ({
|
||||
currentYear, currentMonth, gridDate, minDate, maxDate,
|
||||
)
|
||||
? 'disabled'
|
||||
: `${gridDate ? 'clickable' : ''}`,
|
||||
: gridDate ? 'clickable' : '',
|
||||
selectedDay === formatDay(currentYear, currentMonth, gridDate) && 'selected',
|
||||
)}
|
||||
>
|
||||
|
||||
@ -136,7 +136,7 @@ const DeleteMessageModal: FC<OwnProps & StateProps> = ({
|
||||
const buildNestedOptionListWithAvatars = useLastCallback(() => {
|
||||
return peerList.map((member) => {
|
||||
return {
|
||||
value: `${member.id}`,
|
||||
value: member.id,
|
||||
label: getPeerTitle(lang, member) || '',
|
||||
leftElement: <Avatar size="small" peer={member} />,
|
||||
};
|
||||
|
||||
@ -291,7 +291,7 @@ const StickerButton = <T extends number | ApiSticker | ApiBotInlineMediaResult |
|
||||
onClick={handleClick}
|
||||
onContextMenu={handleContextMenu}
|
||||
>
|
||||
{withSparkles && <Sparkles preset="button" /> }
|
||||
{withSparkles && <Sparkles preset="button" />}
|
||||
{isIntesectingForShowing && (
|
||||
<StickerView
|
||||
containerRef={ref}
|
||||
|
||||
@ -356,7 +356,7 @@ export function insertTextEntity(entities: ApiMessageEntity[], newEntity: ApiMes
|
||||
|
||||
// Organize entities in a tree-like structure to better represent how the text will be displayed
|
||||
function organizeEntities(entities: ApiMessageEntity[]) {
|
||||
const organizedEntityIndexes: Set<number> = new Set();
|
||||
const organizedEntityIndexes = new Set<number>();
|
||||
const organizedEntities: IOrganizedEntity[] = [];
|
||||
|
||||
entities.forEach((entity, index) => {
|
||||
|
||||
@ -83,7 +83,7 @@ export default function useAnimatedEmoji(
|
||||
const { x, y } = container.getBoundingClientRect();
|
||||
|
||||
interactWithAnimatedEmoji({
|
||||
emoji: emoji,
|
||||
emoji,
|
||||
x,
|
||||
y,
|
||||
startSize: size,
|
||||
|
||||
@ -245,12 +245,14 @@ const PeerPicker = <CategoryType extends string = CustomPeerType>({
|
||||
|
||||
const peerOrCategory = peer || category;
|
||||
if (!peerOrCategory) {
|
||||
if (DEBUG) return (
|
||||
<div key={id}>
|
||||
No peer or category with ID
|
||||
{id}
|
||||
</div>
|
||||
);
|
||||
if (DEBUG) {
|
||||
return (
|
||||
<div key={id}>
|
||||
No peer or category with ID
|
||||
{id}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
@ -395,7 +395,7 @@ const ChatExtra: FC<OwnProps & StateProps> = ({
|
||||
{birthday && (
|
||||
<UserBirthday key={peerId} birthday={birthday} user={user!} isInSettings={isInSettings} />
|
||||
)}
|
||||
{ hasMainMiniApp && (
|
||||
{hasMainMiniApp && (
|
||||
<ListItem
|
||||
multiline
|
||||
isStatic
|
||||
|
||||
@ -16,7 +16,7 @@ type OwnProps = {
|
||||
containerId?: string;
|
||||
};
|
||||
|
||||
const revealByContainerId: Map<string, VoidFunction[]> = new Map();
|
||||
const revealByContainerId = new Map<string, VoidFunction[]>();
|
||||
|
||||
const buildClassName = createClassNameBuilder('Spoiler');
|
||||
|
||||
|
||||
@ -190,9 +190,9 @@
|
||||
}
|
||||
|
||||
.search-sponsored-badge {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-self: flex-start;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
@ -550,7 +550,7 @@ const Main = ({
|
||||
});
|
||||
|
||||
// Online status and browser tab indicators
|
||||
useBackgroundMode(handleBlur, handleFocus, !!IS_ELECTRON);
|
||||
useBackgroundMode(handleBlur, handleFocus, Boolean(IS_ELECTRON));
|
||||
useBeforeUnload(handleBlur);
|
||||
usePreventPinchZoomGesture(isMediaViewerOpen || isStoryViewerOpen);
|
||||
|
||||
|
||||
@ -103,7 +103,7 @@ const DEFAULT_CUSTOM_EXPIRE_DATE = 86400 * 3 * 1000; // 3 days
|
||||
const MAX_ADDITIONAL_CHANNELS = 9;
|
||||
const DEFAULT_BOOST_COUNT = 5;
|
||||
|
||||
const GIVEAWAY_IMG_LIST: { [key: number]: string } = {
|
||||
const GIVEAWAY_IMG_LIST: Partial<Record<number, string>> = {
|
||||
3: GiftGreenRound,
|
||||
6: GiftBlueRound,
|
||||
12: GiftRedRound,
|
||||
@ -721,7 +721,11 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
{dataStarsPrepaidGiveaway ? (
|
||||
<img className={styles.prepaidImg} src={GiftStar} alt="" />
|
||||
) : (
|
||||
<img className={styles.prepaidImg} src={GIVEAWAY_IMG_LIST[dataPrepaidGiveaway!.months]} alt="" />
|
||||
<img
|
||||
className={styles.prepaidImg}
|
||||
src={GIVEAWAY_IMG_LIST[dataPrepaidGiveaway!.months] || GIVEAWAY_IMG_LIST[3]}
|
||||
alt=""
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.info}>
|
||||
|
||||
@ -37,7 +37,7 @@ const GiveawayTypeOption: FC<OwnProps> = ({
|
||||
|
||||
let displayText: string | undefined = lang(text);
|
||||
if (isLink && selectedMemberIds?.length) {
|
||||
displayText = selectedMemberIds.length > 2 ? `${selectedMemberIds.length}` : userNames;
|
||||
displayText = selectedMemberIds.length > 2 ? selectedMemberIds.length.toString() : userNames;
|
||||
}
|
||||
|
||||
const handleChange = useLastCallback((e: ChangeEvent<HTMLInputElement>) => {
|
||||
@ -70,7 +70,7 @@ const GiveawayTypeOption: FC<OwnProps> = ({
|
||||
<img className={styles.optionImg} src={img} alt="" draggable={false} />
|
||||
<div className={styles.giveaway}>
|
||||
<h3 className={styles.title}>
|
||||
{lang(`${name}`)}
|
||||
{lang(name)}
|
||||
</h3>
|
||||
{isLink ? (
|
||||
<div className={styles.link} onClick={handleClick}>
|
||||
|
||||
@ -352,14 +352,14 @@ const StickerPicker: FC<OwnProps & StateProps> = ({
|
||||
|
||||
return (
|
||||
<div className={fullClassName}>
|
||||
{ !isForEffects && (
|
||||
{!isForEffects && (
|
||||
<div ref={headerRef} className={headerClassName}>
|
||||
<div className="shared-canvas-container">
|
||||
<canvas ref={sharedCanvasRef} className="shared-canvas" />
|
||||
{allSets.map(renderCover)}
|
||||
</div>
|
||||
</div>
|
||||
) }
|
||||
)}
|
||||
<div
|
||||
ref={containerRef}
|
||||
onMouseMove={handleMouseMove}
|
||||
|
||||
@ -68,7 +68,7 @@ export default async function buildAttachment(
|
||||
const { videoWidth: width, videoHeight: height, duration } = await preloadVideo(blobUrl);
|
||||
shouldSendAsFile = !validateAspectRatio(width, height);
|
||||
if (!shouldSendAsFile) {
|
||||
quick = { width: width, height: height, duration: duration };
|
||||
quick = { width, height, duration };
|
||||
}
|
||||
} catch (err) {
|
||||
shouldSendAsFile = true;
|
||||
|
||||
@ -89,13 +89,13 @@ type StateProps = {
|
||||
isAccountFrozen?: boolean;
|
||||
};
|
||||
|
||||
const SINGLE_LINE_ACTIONS: Set<ApiMessageAction['type']> = new Set([
|
||||
const SINGLE_LINE_ACTIONS = new Set<ApiMessageAction['type']>([
|
||||
'pinMessage',
|
||||
'chatEditPhoto',
|
||||
'chatDeletePhoto',
|
||||
'unsupported',
|
||||
]);
|
||||
const HIDDEN_TEXT_ACTIONS: Set<ApiMessageAction['type']> = new Set(['giftCode', 'prizeStars', 'suggestProfilePhoto']);
|
||||
const HIDDEN_TEXT_ACTIONS = new Set<ApiMessageAction['type']>(['giftCode', 'prizeStars', 'suggestProfilePhoto']);
|
||||
|
||||
const ActionMessage = ({
|
||||
message,
|
||||
|
||||
@ -137,7 +137,7 @@ const CommentButton: FC<OwnProps> = ({
|
||||
)}
|
||||
color={isCustomShape ? 'white' : 'blue'}
|
||||
/>
|
||||
) }
|
||||
)}
|
||||
<Icon
|
||||
name="next"
|
||||
className={buildClassName(
|
||||
|
||||
@ -70,7 +70,7 @@ export default function withSelectControl(WrappedComponent: FC) {
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{ }
|
||||
{}
|
||||
<WrappedComponent {...newProps} />
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -246,7 +246,7 @@ const GiftModal: FC<OwnProps & StateProps> = ({
|
||||
return !isLimited && !isSoldOut;
|
||||
}
|
||||
if (areUnlimitedStarGiftsDisallowed && areLimitedStarGiftsDisallowed) {
|
||||
return Boolean(isLimited && !!upgradeStars);
|
||||
return Boolean(isLimited && Boolean(upgradeStars));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@ -342,7 +342,7 @@ const PaidReactionModal = ({
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
{topReactors && (<Separator className={styles.separator} />) }
|
||||
{topReactors && (<Separator className={styles.separator} />)}
|
||||
<Checkbox
|
||||
className={buildClassName(styles.checkBox, 'dialog-checkbox')}
|
||||
checked={!shouldSendAsAnonymous}
|
||||
|
||||
@ -87,7 +87,7 @@ const StarPaymentModal = ({
|
||||
if (paidMediaMessage) {
|
||||
const extendedMedia = paidMediaMessage.content.paidMedia!.extendedMedia as ApiMediaExtendedPreview[];
|
||||
const areAllPhotos = extendedMedia.every((media) => !media.duration);
|
||||
const areAllVideos = extendedMedia.every((media) => !!media.duration);
|
||||
const areAllVideos = extendedMedia.every((media) => Boolean(media.duration));
|
||||
|
||||
const mediaText = areAllPhotos ? oldLang('Stars.Transfer.Photos', extendedMedia.length)
|
||||
: areAllVideos ? oldLang('Stars.Transfer.Videos', extendedMedia.length)
|
||||
|
||||
@ -68,14 +68,14 @@ const MinimizedWebAppModal = ({
|
||||
function renderTitle() {
|
||||
const activeTabName = peers.length > 0 && peers[0]?.firstName;
|
||||
const title = openedTabsCount && activeTabName && openedTabsCount > 1
|
||||
? `${lang('MiniAppsMoreTabs',
|
||||
? lang('MiniAppsMoreTabs',
|
||||
{
|
||||
botName: activeTabName,
|
||||
count: openedTabsCount - 1,
|
||||
},
|
||||
{
|
||||
pluralValue: openedTabsCount - 1,
|
||||
})}`
|
||||
})
|
||||
: activeTabName;
|
||||
|
||||
return (
|
||||
|
||||
@ -713,7 +713,7 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
|
||||
modalHeight={currentHeight}
|
||||
/>
|
||||
))}
|
||||
{ isMoreAppsTabActive && (<MoreAppsTabContent />)}
|
||||
{isMoreAppsTabActive && (<MoreAppsTabContent />)}
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1109,7 +1109,7 @@ const WebAppModalTabContent: FC<OwnProps & StateProps> = ({
|
||||
{mainButton?.isProgressVisible && <Spinner className={styles.mainButtonSpinner} color="white" />}
|
||||
</Button>
|
||||
</div>
|
||||
) }
|
||||
)}
|
||||
{popupParameters && (
|
||||
<Modal
|
||||
isOpen={Boolean(popupParameters)}
|
||||
|
||||
@ -167,10 +167,10 @@ const ShippingInfo: FC<OwnProps> = ({
|
||||
/>
|
||||
</div>
|
||||
) : undefined}
|
||||
{ needName || needEmail || needPhone ? (
|
||||
{needName || needEmail || needPhone ? (
|
||||
<h5>{oldLang('PaymentShippingReceiver')}</h5>
|
||||
) : undefined }
|
||||
{ needName && (
|
||||
) : undefined}
|
||||
{needName && (
|
||||
<InputText
|
||||
label={oldLang('PaymentShippingName')}
|
||||
onChange={handleFullNameChange}
|
||||
@ -179,8 +179,8 @@ const ShippingInfo: FC<OwnProps> = ({
|
||||
tabIndex={0}
|
||||
error={formErrors.fullName && lang.withRegular(formErrors.fullName)}
|
||||
/>
|
||||
) }
|
||||
{ needEmail && (
|
||||
)}
|
||||
{needEmail && (
|
||||
<InputText
|
||||
label={oldLang('PaymentShippingEmailPlaceholder')}
|
||||
onChange={handleEmailChange}
|
||||
@ -189,8 +189,8 @@ const ShippingInfo: FC<OwnProps> = ({
|
||||
tabIndex={0}
|
||||
error={formErrors.email && lang.withRegular(formErrors.email)}
|
||||
/>
|
||||
) }
|
||||
{ needPhone && (
|
||||
)}
|
||||
{needPhone && (
|
||||
<InputText
|
||||
label={oldLang('PaymentShippingPhoneNumber')}
|
||||
onChange={handlePhoneChange}
|
||||
@ -200,7 +200,7 @@ const ShippingInfo: FC<OwnProps> = ({
|
||||
error={formErrors.phone && lang.withRegular(formErrors.phone)}
|
||||
ref={phoneRef}
|
||||
/>
|
||||
) }
|
||||
)}
|
||||
<Checkbox
|
||||
label={oldLang('PaymentShippingSave')}
|
||||
subLabel={oldLang('PaymentShippingSaveInfo')}
|
||||
|
||||
@ -782,7 +782,7 @@ const Profile: FC<OwnProps & StateProps> = ({
|
||||
))}
|
||||
{!isCurrentUserPremium && (
|
||||
<>
|
||||
{ }
|
||||
{}
|
||||
<Button className="show-more-channels" size="smaller" onClick={() => openPremiumModal()}>
|
||||
{oldLang('UnlockSimilar')}
|
||||
<Icon name="unlock-badge" />
|
||||
@ -821,7 +821,7 @@ const Profile: FC<OwnProps & StateProps> = ({
|
||||
))}
|
||||
{!isCurrentUserPremium && (
|
||||
<>
|
||||
{ }
|
||||
{}
|
||||
<Button className="show-more-bots" size="smaller" onClick={() => openPremiumModal()}>
|
||||
{lang('UnlockMoreSimilarBots')}
|
||||
<Icon name="unlock-badge" />
|
||||
|
||||
@ -167,7 +167,7 @@ const ManageBot: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const handleChangeSettings = useLastCallback(() => {
|
||||
startBotFatherConversation({ param: `${username}` });
|
||||
startBotFatherConversation({ param: username! });
|
||||
});
|
||||
|
||||
const inputRef = useRef<HTMLInputElement>();
|
||||
|
||||
@ -200,7 +200,7 @@ const ManageChannel: FC<OwnProps & StateProps> = ({
|
||||
const enabledLength = chatFullInfo.enabledReactions.allowed.length;
|
||||
const totalLength = availableReactions?.filter((reaction) => !reaction.isInactive).length || 0;
|
||||
|
||||
return totalLength ? `${enabledLength} / ${totalLength}` : `${enabledLength}`;
|
||||
return totalLength ? `${enabledLength} / ${totalLength}` : enabledLength.toString();
|
||||
}, [availableReactions, chatFullInfo?.enabledReactions, lang]);
|
||||
const isChannelPublic = useMemo(() => isChatPublic(chat), [chat]);
|
||||
|
||||
|
||||
@ -270,7 +270,7 @@ const ManageGroup: FC<OwnProps & StateProps> = ({
|
||||
|
||||
return totalLength
|
||||
? `${enabledLength} / ${totalLength}`
|
||||
: `${enabledLength}`;
|
||||
: enabledLength.toString();
|
||||
}, [availableReactions, chatFullInfo?.enabledReactions, lang]);
|
||||
|
||||
const enabledPermissionsCount = useMemo(() => {
|
||||
|
||||
@ -192,7 +192,7 @@ const ManageReactions: FC<OwnProps & StateProps> = ({
|
||||
return (
|
||||
<div className="Management">
|
||||
<div className="panel-content custom-scroll">
|
||||
{ Boolean(localReactionsLimit && shouldShowReactionsLimit) && (
|
||||
{Boolean(localReactionsLimit && shouldShowReactionsLimit) && (
|
||||
<div className="section">
|
||||
<h3 className="section-heading">
|
||||
{lang('MaximumReactionsHeader')}
|
||||
|
||||
@ -50,7 +50,7 @@ type StateProps = {
|
||||
isChannel?: boolean;
|
||||
};
|
||||
|
||||
const GIVEAWAY_IMG_LIST: { [key: number]: string } = {
|
||||
const GIVEAWAY_IMG_LIST: Partial<Record<number, string>> = {
|
||||
3: GiftGreenRound,
|
||||
6: GiftBlueRound,
|
||||
12: GiftRedRound,
|
||||
@ -319,7 +319,7 @@ const BoostStatistics = ({
|
||||
/>
|
||||
) : (
|
||||
<img
|
||||
src={GIVEAWAY_IMG_LIST[prepaidGiveaway.months]}
|
||||
src={GIVEAWAY_IMG_LIST[prepaidGiveaway.months] || GIVEAWAY_IMG_LIST[3]}
|
||||
className={styles.giveawayIcon}
|
||||
alt={lang('Giveaway')}
|
||||
/>
|
||||
|
||||
@ -13,7 +13,7 @@ const RIBBON_Z_INDEX = 11;
|
||||
const STROKE_OFFSET = 0.1875 * REM;
|
||||
const CANVAS_OFFSET = 0.125 * REM;
|
||||
|
||||
const callbacks: Set<NoneToVoidFunction> = new Set();
|
||||
const callbacks = new Set<NoneToVoidFunction>();
|
||||
|
||||
export function animateOpening(isArchived?: boolean) {
|
||||
cancelDelayedCallbacks();
|
||||
@ -99,7 +99,7 @@ export function animateOpening(isArchived?: boolean) {
|
||||
applyStyles(ghost, {
|
||||
top: `${toTop}px`,
|
||||
left: `${toLeft}px`,
|
||||
zIndex: `${zIndex}`,
|
||||
zIndex: String(zIndex),
|
||||
opacity: ghost2 ? '0' : '',
|
||||
transform: `translate3d(${fromTranslateX}px, ${fromTranslateY}px, 0) scale(${fromScale})`,
|
||||
});
|
||||
@ -108,7 +108,7 @@ export function animateOpening(isArchived?: boolean) {
|
||||
applyStyles(ghost2, {
|
||||
top: `${fromTop}px`,
|
||||
left: `${fromLeft}px`,
|
||||
zIndex: `${zIndex}`,
|
||||
zIndex: String(zIndex),
|
||||
});
|
||||
}
|
||||
|
||||
@ -238,14 +238,14 @@ export function animateClosing(isArchived?: boolean) {
|
||||
top: `${fromTop}px`,
|
||||
left: `${fromLeft}px`,
|
||||
width: `${fromWidth}px`,
|
||||
zIndex: `${zIndex}`,
|
||||
zIndex: String(zIndex),
|
||||
});
|
||||
|
||||
if (ghost2) {
|
||||
applyStyles(ghost2, {
|
||||
top: `${toTop}px`,
|
||||
left: `${toLeft}px`,
|
||||
zIndex: `${zIndex}`,
|
||||
zIndex: String(zIndex),
|
||||
opacity: '0',
|
||||
transform: `translate3d(${fromTranslateX}px, ${fromTranslateY}px, 0) scale(${fromScale})`,
|
||||
});
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* eslint-disable no-template-curly-in-string */
|
||||
const config = {
|
||||
productName: 'Telegram A',
|
||||
artifactName: '${productName}-${arch}.${ext}',
|
||||
|
||||
@ -337,7 +337,7 @@ addActionHandler('queryInlineBot', async (global, actions, payload): Promise<voi
|
||||
void runDebouncedForSearch(() => {
|
||||
searchInlineBot(global, {
|
||||
username,
|
||||
inlineBotData: inlineBotData,
|
||||
inlineBotData,
|
||||
chatId,
|
||||
query,
|
||||
offset,
|
||||
|
||||
@ -427,7 +427,7 @@ addActionHandler('openThread', async (global, actions, payload): Promise<void> =
|
||||
if (focusMessageId) {
|
||||
actions.focusMessage({
|
||||
chatId,
|
||||
threadId: threadId,
|
||||
threadId,
|
||||
messageId: focusMessageId,
|
||||
tabId,
|
||||
});
|
||||
@ -464,7 +464,7 @@ addActionHandler('openThread', async (global, actions, payload): Promise<void> =
|
||||
actions.processOpenChatOrThread({
|
||||
chatId,
|
||||
type,
|
||||
threadId: threadId,
|
||||
threadId,
|
||||
tabId,
|
||||
isComments,
|
||||
noForumTopicPanel,
|
||||
|
||||
@ -15,7 +15,7 @@ export default function useEnsureMessage(
|
||||
useEffect(() => {
|
||||
if (isDisabled) return;
|
||||
if (messageId && !message) {
|
||||
loadMessage({ chatId, messageId: messageId, replyOriginForId: replyOriginForId! });
|
||||
loadMessage({ chatId, messageId, replyOriginForId: replyOriginForId! });
|
||||
}
|
||||
}, [isDisabled, chatId, message, messageId, replyOriginForId]);
|
||||
}
|
||||
|
||||
@ -9,4 +9,4 @@ insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
indent_size = 2
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
tl/api.d.ts
|
||||
tl/apiTl.ts
|
||||
tl/schemaTl.ts
|
||||
tl/apiTl.full.ts
|
||||
tl/schemaTl.full.ts
|
||||
@ -1,35 +0,0 @@
|
||||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"root": true,
|
||||
"rules": {
|
||||
"indent": [
|
||||
"error",
|
||||
4,
|
||||
{
|
||||
"SwitchCase": 1
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/indent": [
|
||||
"error",
|
||||
4,
|
||||
{
|
||||
"SwitchCase": 1
|
||||
}
|
||||
],
|
||||
"max-len": [
|
||||
"error",
|
||||
120
|
||||
],
|
||||
"no-bitwise": "off",
|
||||
"no-underscore-dangle": "off",
|
||||
"no-continue": "off",
|
||||
"no-restricted-syntax": "off",
|
||||
"class-methods-use-this": "off",
|
||||
"max-classes-per-file": "off",
|
||||
"camelcase": "off"
|
||||
},
|
||||
"ignorePatterns": ["client/mockUtils/*", "client/__invokeMiddlewares__/*"]
|
||||
}
|
||||
@ -45,7 +45,7 @@ const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
|
||||
const FILTERED_ATTRIBUTES = new Set(['key', 'ref', 'teactFastList', 'teactOrderKey']);
|
||||
const HTML_ATTRIBUTES = new Set(['dir', 'role', 'form']);
|
||||
const CONTROLLABLE_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];
|
||||
const MAPPED_ATTRIBUTES: { [k: string]: string } = {
|
||||
const MAPPED_ATTRIBUTES: Partial<Record<string, string>> = {
|
||||
autoCapitalize: 'autocapitalize',
|
||||
autoComplete: 'autocomplete',
|
||||
autoCorrect: 'autocorrect',
|
||||
|
||||
@ -15,7 +15,7 @@ const connections = launchMediaWorkers();
|
||||
let videoPreview: VideoPreview | undefined;
|
||||
|
||||
export class VideoPreview {
|
||||
frames: Map<number, ImageBitmap> = new Map();
|
||||
frames = new Map<number, ImageBitmap>();
|
||||
|
||||
currentTime = 0;
|
||||
|
||||
|
||||
@ -61,9 +61,7 @@ export type SharedSessionData = {
|
||||
date?: number;
|
||||
dcId: number;
|
||||
isTest?: true;
|
||||
} & {
|
||||
[K in `dc${DcId}_${'auth_key' | 'server_salt'}`]?: string;
|
||||
} & SessionUserInfo;
|
||||
} & Partial<Record<`dc${DcId}_${'auth_key' | 'server_salt'}`, string>> & SessionUserInfo;
|
||||
|
||||
export type AccountInfo = {
|
||||
isTest?: true;
|
||||
@ -103,9 +101,7 @@ export type PerformanceTypeKey = (
|
||||
| 'animatedEmoji' | 'loopAnimatedStickers' | 'reactionEffects' | 'stickerEffects' | 'autoplayGifs' | 'autoplayVideos'
|
||||
| 'storyRibbonAnimations' | 'snapEffect'
|
||||
);
|
||||
export type PerformanceType = {
|
||||
[key in PerformanceTypeKey]: boolean;
|
||||
};
|
||||
export type PerformanceType = Record<PerformanceTypeKey, boolean>;
|
||||
|
||||
export interface IThemeSettings {
|
||||
background?: string;
|
||||
|
||||
@ -140,7 +140,7 @@ class ConnectorClass<T extends InputRequestTypes> {
|
||||
const requestState = { messageId } as RequestState;
|
||||
|
||||
// Re-wrap type because of `postMessage`
|
||||
const promise: Promise<any> = new Promise((resolve, reject) => {
|
||||
const promise = new Promise<any>((resolve, reject) => {
|
||||
Object.assign(requestState, { resolve, reject });
|
||||
});
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ import { animate } from './animation';
|
||||
|
||||
const DEFAULT_DURATION = 300;
|
||||
|
||||
const stopById: Map<string, VoidFunction> = new Map();
|
||||
const stopById = new Map<string, VoidFunction>();
|
||||
|
||||
export default function animateHorizontalScroll(container: HTMLElement, left: number, duration = DEFAULT_DURATION) {
|
||||
if (!selectCanAnimateInterface(getGlobal())) {
|
||||
|
||||
@ -22,7 +22,7 @@ type CustomEmojiInputRenderCallback = (emojiId: string) => void;
|
||||
|
||||
const DOM_PROCESS_THROTTLE = 500;
|
||||
|
||||
const INPUT_WAITING_CUSTOM_EMOJI_IDS: Set<string> = new Set();
|
||||
const INPUT_WAITING_CUSTOM_EMOJI_IDS = new Set<string>();
|
||||
|
||||
const handlers = new Map<CustomEmojiLoadCallback, string>();
|
||||
const renderCallbacks = createCallbackManager<CustomEmojiInputRenderCallback>();
|
||||
|
||||
@ -4,9 +4,7 @@ type OrderDirection =
|
||||
'asc'
|
||||
| 'desc';
|
||||
|
||||
interface OrderCallback<T> {
|
||||
(member: T): any;
|
||||
}
|
||||
type OrderCallback<T> = (member: T) => unknown;
|
||||
|
||||
export function buildCollectionByKey<T extends AnyLiteral>(collection: T[], key: keyof T) {
|
||||
return collection.reduce((byKey: CollectionByKey<T>, member: T) => {
|
||||
@ -82,6 +80,7 @@ export function orderBy<T>(
|
||||
const aValue = (typeof currentOrderRule === 'function' ? currentOrderRule(a) : a[currentOrderRule]) || 0;
|
||||
const bValue = (typeof currentOrderRule === 'function' ? currentOrderRule(b) : b[currentOrderRule]) || 0;
|
||||
|
||||
// @ts-expect-error Rely on the JS to handle the comparison
|
||||
return isAsc ? aValue - bValue : bValue - aValue;
|
||||
}
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
"noImplicitReturns": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user