From 41a67c9bafc233511ccfed281c3fdcbf9acf8733 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Fri, 25 Mar 2022 13:14:45 +0100 Subject: [PATCH] [Refactoring] ESLint: Add `addCallback` where possible (#1780) --- .eslintrc | 4 +- src/components/auth/AuthRegister.tsx | 12 +-- src/components/auth/CountryCodeInput.tsx | 1 + src/components/calls/CallFallbackConfirm.tsx | 12 ++- src/components/calls/group/GroupCall.tsx | 27 ++++--- src/components/common/CalendarModal.tsx | 4 +- src/components/common/ChatExtra.tsx | 3 + src/components/common/ChatOrUserPicker.tsx | 1 + src/components/common/Picker.tsx | 1 + src/components/common/ReportMessageModal.tsx | 4 +- src/components/common/SeenByModal.tsx | 1 + src/components/common/StickerButton.tsx | 20 ++--- src/components/left/LeftColumn.tsx | 4 +- src/components/left/NewChatButton.tsx | 10 +-- src/components/left/main/ContactList.tsx | 1 + src/components/left/main/LeftMainHeader.tsx | 9 ++- src/components/left/newChat/NewChatStep2.tsx | 1 + .../left/search/LeftSearchResultChat.tsx | 6 +- .../left/settings/SettingsDataStorage.tsx | 17 +++- .../left/settings/SettingsGeneral.tsx | 20 ++++- .../left/settings/SettingsHeader.tsx | 1 + src/components/left/settings/SettingsMain.tsx | 6 ++ .../left/settings/SettingsNotifications.tsx | 80 ++++++++++++------- .../left/settings/SettingsPrivacy.tsx | 8 ++ .../settings/SettingsPrivacyVisibility.tsx | 2 + .../left/settings/SettingsStickerSet.tsx | 2 + .../folders/SettingsFoldersChatsPicker.tsx | 2 + .../settings/folders/SettingsFoldersEdit.tsx | 9 ++- .../settings/folders/SettingsFoldersMain.tsx | 2 + .../twoFa/SettingsTwoFaCongratulations.tsx | 6 +- .../settings/twoFa/SettingsTwoFaEmailCode.tsx | 6 +- .../settings/twoFa/SettingsTwoFaEnabled.tsx | 3 + .../twoFa/SettingsTwoFaSkippableForm.tsx | 14 ++-- src/components/main/AppInactive.tsx | 10 ++- src/components/main/Dialogs.tsx | 16 +++- src/components/main/Notifications.tsx | 1 + .../mediaViewer/VideoPlayerControls.tsx | 1 + src/components/mediaViewer/ZoomControls.tsx | 8 +- src/components/middle/MobileSearch.tsx | 1 + src/components/middle/ReactorListModal.tsx | 3 + src/components/middle/composer/BotCommand.tsx | 1 + .../middle/composer/BotKeyboardMenu.tsx | 9 ++- .../middle/composer/EmojiPicker.tsx | 1 + .../middle/composer/MentionTooltip.tsx | 1 + src/components/middle/composer/PollModal.tsx | 8 +- src/components/middle/composer/SendAsMenu.tsx | 1 + .../middle/composer/StickerPicker.tsx | 1 + .../middle/composer/SymbolMenuFooter.tsx | 1 + .../middle/composer/TextFormatter.tsx | 8 +- .../middle/composer/WebPagePreview.tsx | 12 +-- .../middle/message/InlineButtons.tsx | 1 + .../middle/message/SponsoredMessage.tsx | 15 ++-- src/components/right/PollAnswerResults.tsx | 1 + src/components/right/Profile.tsx | 2 + src/components/right/RightHeader.tsx | 1 + .../right/management/ManageChannel.tsx | 8 +- .../management/ManageChatAdministrators.tsx | 5 +- .../right/management/ManageDiscussion.tsx | 1 + .../right/management/ManageGroup.tsx | 8 +- .../right/management/ManageGroupMembers.tsx | 1 + .../management/ManageGroupPermissions.tsx | 1 + .../ManageGroupUserPermissionsCreate.tsx | 1 + .../right/management/ManageInviteInfo.tsx | 3 + .../right/management/ManageInvites.tsx | 2 + src/components/test/TestOrdered.tsx | 2 + src/components/ui/AvatarEditable.tsx | 10 +-- src/components/ui/CropModal.tsx | 6 +- src/components/ui/DropdownMenu.tsx | 8 +- 68 files changed, 306 insertions(+), 152 deletions(-) diff --git a/.eslintrc b/.eslintrc index c6f0eb43a..2c72e2686 100644 --- a/.eslintrc +++ b/.eslintrc @@ -73,8 +73,8 @@ "react/style-prop-object": "off", "react/jsx-no-bind": ["error", { "ignoreRefs": true, - "allowArrowFunctions": true, - "allowFunctions": true, + "allowArrowFunctions": false, + "allowFunctions": false, "allowBind": false, "ignoreDOMComponents": true }], diff --git a/src/components/auth/AuthRegister.tsx b/src/components/auth/AuthRegister.tsx index 566414578..4b50e7cc0 100644 --- a/src/components/auth/AuthRegister.tsx +++ b/src/components/auth/AuthRegister.tsx @@ -1,5 +1,7 @@ import { ChangeEvent } from 'react'; -import React, { FC, useState, memo } from '../../lib/teact/teact'; +import React, { + FC, useState, memo, useCallback, +} from '../../lib/teact/teact'; import { getActions, withGlobal } from '../../global'; import { GlobalState } from '../../global/types'; @@ -24,7 +26,7 @@ const AuthRegister: FC = ({ const [firstName, setFirstName] = useState(''); const [lastName, setLastName] = useState(''); - function handleFirstNameChange(event: ChangeEvent) { + const handleFirstNameChange = useCallback((event: ChangeEvent) => { if (authError) { clearAuthError(); } @@ -33,13 +35,13 @@ const AuthRegister: FC = ({ setFirstName(target.value); setIsButtonShown(target.value.length > 0); - } + }, [authError, clearAuthError]); - function handleLastNameChange(event: ChangeEvent) { + const handleLastNameChange = useCallback((event: ChangeEvent) => { const { target } = event; setLastName(target.value); - } + }, []); function handleSubmit(event: React.FormEvent) { event.preventDefault(); diff --git a/src/components/auth/CountryCodeInput.tsx b/src/components/auth/CountryCodeInput.tsx index 7f1a57a02..943eb1c16 100644 --- a/src/components/auth/CountryCodeInput.tsx +++ b/src/components/auth/CountryCodeInput.tsx @@ -138,6 +138,7 @@ const CountryCodeInput: FC = ({ handleChange(country)} > {renderText(isoToEmoji(country.iso2), ['hq_emoji'])} diff --git a/src/components/calls/CallFallbackConfirm.tsx b/src/components/calls/CallFallbackConfirm.tsx index d455846c8..0b6a92716 100644 --- a/src/components/calls/CallFallbackConfirm.tsx +++ b/src/components/calls/CallFallbackConfirm.tsx @@ -1,4 +1,6 @@ -import React, { FC, memo, useState } from '../../lib/teact/teact'; +import React, { + FC, memo, useCallback, useState, +} from '../../lib/teact/teact'; import { getActions, withGlobal } from '../../global'; import ConfirmDialog from '../ui/ConfirmDialog'; @@ -30,13 +32,15 @@ const CallFallbackConfirm: FC = ({ const [shouldRemove, setShouldRemove] = useState(true); const renderingUserFullName = useCurrentOrPrev(userFullName, true); + const handleConfirm = useCallback(() => { + inviteToCallFallback({ shouldRemove }); + }, [inviteToCallFallback, shouldRemove]); + return ( { - inviteToCallFallback({ shouldRemove }); - }} + confirmHandler={handleConfirm} onClose={closeCallFallbackConfirm} >

The call will be started in a private channel {channelTitle}.

diff --git a/src/components/calls/group/GroupCall.tsx b/src/components/calls/group/GroupCall.tsx index ccfe05aea..71334a4e5 100644 --- a/src/components/calls/group/GroupCall.tsx +++ b/src/components/calls/group/GroupCall.tsx @@ -123,10 +123,10 @@ const GroupCall: FC = ({ } }, [connectionState, playGroupCallSound]); - const handleCloseConfirmLeaveModal = () => { + const handleCloseConfirmLeaveModal = useCallback(() => { closeConfirmLeaveModal(); setIsEndGroupCallModal(false); - }; + }, [closeConfirmLeaveModal]); const MainButton: FC<{ onTrigger: () => void; isOpen?: boolean }> = useMemo(() => { return ({ onTrigger, isOpen }) => ( @@ -153,13 +153,13 @@ const GroupCall: FC = ({ } }, [closeFullscreen, isFullscreen, openFullscreen]); - const handleToggleSidebar = () => { + const handleToggleSidebar = useCallback(() => { if (isSidebarOpen) { closeSidebar(); } else { openSidebar(); } - }; + }, [closeSidebar, isSidebarOpen, openSidebar]); const handleStreamsDoubleClick = useCallback(() => { if (!IS_REQUEST_FULLSCREEN_SUPPORTED) return; @@ -180,12 +180,12 @@ const GroupCall: FC = ({ } }, [closeFullscreen, isFullscreen, openFullscreen]); - const handleClose = () => { + const handleClose = useCallback(() => { toggleGroupCallPanel(); if (isFullscreen) { closeFullscreen(); } - }; + }, [closeFullscreen, isFullscreen, toggleGroupCallPanel]); useEffect(() => { if (!IS_REQUEST_FULLSCREEN_SUPPORTED) return undefined; @@ -211,16 +211,16 @@ const GroupCall: FC = ({ connectToActiveGroupCall(); }, [connectToActiveGroupCall, groupCallId]); - const endGroupCall = () => { + const endGroupCall = useCallback(() => { setIsEndGroupCallModal(true); setShouldEndGroupCall(true); openConfirmLeaveModal(); if (isFullscreen) { handleToggleFullscreen(); } - }; + }, [handleToggleFullscreen, isFullscreen, openConfirmLeaveModal]); - const handleLeaveGroupCall = () => { + const handleLeaveGroupCall = useCallback(() => { if (isAdmin && !isConfirmLeaveModalOpen) { openConfirmLeaveModal(); if (isFullscreen) { @@ -231,15 +231,18 @@ const GroupCall: FC = ({ playGroupCallSound({ sound: 'leave' }); setIsLeaving(true); closeConfirmLeaveModal(); - }; + }, [ + closeConfirmLeaveModal, handleToggleFullscreen, isAdmin, isConfirmLeaveModalOpen, isFullscreen, + openConfirmLeaveModal, playGroupCallSound, + ]); - const handleCloseAnimationEnd = () => { + const handleCloseAnimationEnd = useCallback(() => { if (isLeaving) { leaveGroupCall({ shouldDiscard: shouldEndGroupCall, }); } - }; + }, [isLeaving, leaveGroupCall, shouldEndGroupCall]); return ( = ({ }); } - function handleSubmit() { + const handleSubmit = useCallback(() => { onSubmit(selectedDate); - } + }, [onSubmit, selectedDate]); const handleChangeHours = useCallback((e: React.ChangeEvent) => { const value = e.target.value.replace(/[^\d]+/g, ''); diff --git a/src/components/common/ChatExtra.tsx b/src/components/common/ChatExtra.tsx index f90dd33a6..ce9d84b54 100644 --- a/src/components/common/ChatExtra.tsx +++ b/src/components/common/ChatExtra.tsx @@ -86,6 +86,7 @@ const ChatExtra: FC = ({ return (
{formattedNumber && Boolean(formattedNumber.length) && ( + // eslint-disable-next-line react/jsx-no-bind copy(formattedNumber, lang('Phone'))}> {formattedNumber} {lang('Phone')} @@ -97,6 +98,7 @@ const ChatExtra: FC = ({ multiline narrow ripple + // eslint-disable-next-line react/jsx-no-bind onClick={() => copy(`@${username}`, lang('Username'))} > {renderText(username)} @@ -122,6 +124,7 @@ const ChatExtra: FC = ({ multiline narrow ripple + // eslint-disable-next-line react/jsx-no-bind onClick={() => copy(link, lang('SetUrlPlaceholder'))} >
{link}
diff --git a/src/components/common/ChatOrUserPicker.tsx b/src/components/common/ChatOrUserPicker.tsx index 14bd1c46c..00ba0dcf1 100644 --- a/src/components/common/ChatOrUserPicker.tsx +++ b/src/components/common/ChatOrUserPicker.tsx @@ -113,6 +113,7 @@ const ChatOrUserPicker: FC = ({ key={id} className="chat-item-clickable force-rounded-corners" style={`top: ${(viewportOffset + i) * CHAT_HEIGHT_PX}px;`} + // eslint-disable-next-line react/jsx-no-bind onClick={() => onSelectChatOrUser(id)} > {isUserId(id) ? ( diff --git a/src/components/common/Picker.tsx b/src/components/common/Picker.tsx index 13c006c2b..70c579ce4 100644 --- a/src/components/common/Picker.tsx +++ b/src/components/common/Picker.tsx @@ -115,6 +115,7 @@ const Picker: FC = ({ handleItemClick(id)} ripple > diff --git a/src/components/common/ReportMessageModal.tsx b/src/components/common/ReportMessageModal.tsx index 51a7ba4d1..8e7c9deca 100644 --- a/src/components/common/ReportMessageModal.tsx +++ b/src/components/common/ReportMessageModal.tsx @@ -33,11 +33,11 @@ const ReportMessageModal: FC = ({ const [selectedReason, setSelectedReason] = useState('spam'); const [description, setDescription] = useState(''); - const handleReport = () => { + const handleReport = useCallback(() => { reportMessages({ messageIds, reason: selectedReason, description }); exitMessageSelectMode(); onClose(); - }; + }, [description, exitMessageSelectMode, messageIds, onClose, reportMessages, selectedReason]); const handleSelectReason = useCallback((value: string) => { setSelectedReason(value as ApiReportReason); diff --git a/src/components/common/SeenByModal.tsx b/src/components/common/SeenByModal.tsx index 3bc4a517e..5be4f4bef 100644 --- a/src/components/common/SeenByModal.tsx +++ b/src/components/common/SeenByModal.tsx @@ -53,6 +53,7 @@ const SeenByModal: FC = ({ handleClick(userId)} > diff --git a/src/components/common/StickerButton.tsx b/src/components/common/StickerButton.tsx index 67cccb5c4..ccb7be8ff 100644 --- a/src/components/common/StickerButton.tsx +++ b/src/components/common/StickerButton.tsx @@ -140,28 +140,28 @@ const StickerButton = ) => { + const handleUnfaveClick = useCallback((e: ReactMouseEvent) => { e.stopPropagation(); e.preventDefault(); onUnfaveClick!(sticker); - }; + }, [onUnfaveClick, sticker]); - const handleContextUnfave = () => { + const handleContextUnfave = useCallback(() => { onUnfaveClick!(sticker); - }; + }, [onUnfaveClick, sticker]); - const handleContextFave = () => { + const handleContextFave = useCallback(() => { onFaveClick!(sticker); - }; + }, [onFaveClick, sticker]); - const handleSendQuiet = () => { + const handleSendQuiet = useCallback(() => { onClick?.(clickArg, true); - }; + }, [clickArg, onClick]); - const handleSendScheduled = () => { + const handleSendScheduled = useCallback(() => { onClick?.(clickArg, undefined, true); - }; + }, [clickArg, onClick]); const fullClassName = buildClassName( 'StickerButton', diff --git a/src/components/left/LeftColumn.tsx b/src/components/left/LeftColumn.tsx index e7b344651..696863ed6 100644 --- a/src/components/left/LeftColumn.tsx +++ b/src/components/left/LeftColumn.tsx @@ -286,10 +286,10 @@ const LeftColumn: FC = ({ initResize, resetResize, handleMouseUp, } = useResize(resizeRef, setLeftColumnWidth, resetLeftColumnWidth, leftColumnWidth); - const handleSettingsScreenSelect = (screen: SettingsScreens) => { + const handleSettingsScreenSelect = useCallback((screen: SettingsScreens) => { setContent(LeftColumnContent.Settings); setSettingsScreen(screen); - }; + }, []); return (
= ({ isMenuOpen && 'menu-is-open', ); - const toggleIsMenuOpen = () => { + const toggleIsMenuOpen = useCallback(() => { setIsMenuOpen(!isMenuOpen); - }; + }, [isMenuOpen]); - const handleClose = () => { + const handleClose = useCallback(() => { setIsMenuOpen(false); - }; + }, []); return (
diff --git a/src/components/left/main/ContactList.tsx b/src/components/left/main/ContactList.tsx index 62e7ad404..04210ba02 100644 --- a/src/components/left/main/ContactList.tsx +++ b/src/components/left/main/ContactList.tsx @@ -83,6 +83,7 @@ const ContactList: FC = ({ handleClick(id)} ripple={!IS_SINGLE_COLUMN_LAYOUT} > diff --git a/src/components/left/main/LeftMainHeader.tsx b/src/components/left/main/LeftMainHeader.tsx index 81e45294b..298087d24 100644 --- a/src/components/left/main/LeftMainHeader.tsx +++ b/src/components/left/main/LeftMainHeader.tsx @@ -134,6 +134,7 @@ const LeftMainHeader: FC = ({ size="smaller" color="translucent" className={isOpen ? 'active' : ''} + // eslint-disable-next-line react/jsx-no-bind onClick={hasMenu ? onTrigger : () => onReset()} ariaLabel={hasMenu ? lang('AccDescrOpenMenu2') : 'Return to chat list'} > @@ -181,15 +182,15 @@ const LeftMainHeader: FC = ({ setSettingOption({ animationLevel: newLevel }); }, [animationLevel, setSettingOption]); - const handleSwitchToWebK = () => { + const handleSwitchToWebK = useCallback(() => { setPermanentWebVersion('K'); clearWebsync(); disableHistoryBack(); - }; + }, []); - const handleOpenTipsChat = () => { + const handleOpenTipsChat = useCallback(() => { openTipsChat({ langCode: lang.code }); - }; + }, [lang.code, openTipsChat]); const isSearchFocused = ( Boolean(globalSearchChatId) diff --git a/src/components/left/newChat/NewChatStep2.tsx b/src/components/left/newChat/NewChatStep2.tsx index 3ca88a184..05608c3aa 100644 --- a/src/components/left/newChat/NewChatStep2.tsx +++ b/src/components/left/newChat/NewChatStep2.tsx @@ -125,6 +125,7 @@ const NewChatStep2: FC = ({ round size="smaller" color="translucent" + // eslint-disable-next-line react/jsx-no-bind onClick={() => onReset()} ariaLabel="Return to member selection" > diff --git a/src/components/left/search/LeftSearchResultChat.tsx b/src/components/left/search/LeftSearchResultChat.tsx index 60cd6172c..63a141454 100644 --- a/src/components/left/search/LeftSearchResultChat.tsx +++ b/src/components/left/search/LeftSearchResultChat.tsx @@ -1,5 +1,5 @@ import React, { - FC, memo, + FC, memo, useCallback, } from '../../../lib/teact/teact'; import { withGlobal } from '../../../global'; @@ -56,9 +56,9 @@ const LeftSearchResultChat: FC = ({ handleChatFolderChange: openChatFolderModal, }, true); - const handleClick = () => { + const handleClick = useCallback(() => { onClick(chatId); - }; + }, [chatId, onClick]); const buttonRef = useSelectWithEnter(handleClick); diff --git a/src/components/left/settings/SettingsDataStorage.tsx b/src/components/left/settings/SettingsDataStorage.tsx index 54883dbfd..c829ba584 100644 --- a/src/components/left/settings/SettingsDataStorage.tsx +++ b/src/components/left/settings/SettingsDataStorage.tsx @@ -69,6 +69,14 @@ const SettingsDataStorage: FC = ({ setSettingOption({ autoLoadFileMaxSizeMb: AUTODOWNLOAD_FILESIZE_MB_LIMITS[value] }); }, [setSettingOption]); + const handleCanAutoPlayGifsChange = useCallback((value: boolean) => { + setSettingOption({ canAutoPlayGifs: value }); + }, [setSettingOption]); + + const handleCanAutoPlayVideosChange = useCallback((value: boolean) => { + setSettingOption({ canAutoPlayVideos: value }); + }, [setSettingOption]); + function renderContentSizeSlider() { const value = AUTODOWNLOAD_FILESIZE_MB_LIMITS.indexOf(autoLoadFileMaxSizeMb); @@ -101,21 +109,26 @@ const SettingsDataStorage: FC = ({ setSettingOption({ [`canAutoLoad${key}FromContacts`]: isChecked })} /> setSettingOption({ [`canAutoLoad${key}InPrivateChats`]: isChecked })} /> setSettingOption({ [`canAutoLoad${key}InGroups`]: isChecked })} /> setSettingOption({ [`canAutoLoad${key}InChannels`]: isChecked })} /> @@ -157,12 +170,12 @@ const SettingsDataStorage: FC = ({ setSettingOption({ canAutoPlayGifs: isChecked })} + onCheck={handleCanAutoPlayGifsChange} /> setSettingOption({ canAutoPlayVideos: isChecked })} + onCheck={handleCanAutoPlayVideosChange} />
diff --git a/src/components/left/settings/SettingsGeneral.tsx b/src/components/left/settings/SettingsGeneral.tsx index 804efb6fa..2f69e0443 100644 --- a/src/components/left/settings/SettingsGeneral.tsx +++ b/src/components/left/settings/SettingsGeneral.tsx @@ -122,6 +122,18 @@ const SettingsGeneral: FC = ({ openModal(); }, [openModal]); + const handleMessageSendComboChange = useCallback((newCombo: string) => { + setSettingOption({ messageSendKeyCombo: newCombo }); + }, [setSettingOption]); + + const handleSuggestStickersChange = useCallback((newValue: boolean) => { + setSettingOption({ shouldSuggestStickers: newValue }); + }, [setSettingOption]); + + const handleShouldLoopStickersChange = useCallback((newValue: boolean) => { + setSettingOption({ shouldLoopStickers: newValue }); + }, [setSettingOption]); + const stickerSets = stickerSetIds && stickerSetIds.map((id: string) => { return stickerSetsById?.[id]?.installedDate ? stickerSetsById[id] : false; }).filter(Boolean as any); @@ -143,6 +155,7 @@ const SettingsGeneral: FC = ({ onScreenSelect(SettingsScreens.GeneralChatBackground)} > {lang('ChatBackground')} @@ -183,7 +196,7 @@ const SettingsGeneral: FC = ({ setSettingOption({ messageSendKeyCombo: value })} + onChange={handleMessageSendComboChange} selected={messageSendKeyCombo} />
@@ -195,6 +208,7 @@ const SettingsGeneral: FC = ({ {defaultReaction && ( onScreenSelect(SettingsScreens.QuickReaction)} > @@ -205,12 +219,12 @@ const SettingsGeneral: FC = ({ setSettingOption({ shouldSuggestStickers: isChecked })} + onCheck={handleSuggestStickersChange} /> setSettingOption({ shouldLoopStickers: isChecked })} + onCheck={handleShouldLoopStickersChange} />
diff --git a/src/components/left/settings/SettingsHeader.tsx b/src/components/left/settings/SettingsHeader.tsx index d0162d6b9..409491855 100644 --- a/src/components/left/settings/SettingsHeader.tsx +++ b/src/components/left/settings/SettingsHeader.tsx @@ -215,6 +215,7 @@ const SettingsHeader: FC = ({ ripple={!IS_SINGLE_COLUMN_LAYOUT} size="smaller" color="translucent" + // eslint-disable-next-line react/jsx-no-bind onClick={() => onScreenSelect(SettingsScreens.EditProfile)} ariaLabel={lang('lng_settings_information')} > diff --git a/src/components/left/settings/SettingsMain.tsx b/src/components/left/settings/SettingsMain.tsx index 8bca6c762..a0efe7325 100644 --- a/src/components/left/settings/SettingsMain.tsx +++ b/src/components/left/settings/SettingsMain.tsx @@ -60,36 +60,42 @@ const SettingsMain: FC = ({ )} onScreenSelect(SettingsScreens.General)} > {lang('Telegram.GeneralSettingsViewController')} onScreenSelect(SettingsScreens.Notifications)} > {lang('Notifications')} onScreenSelect(SettingsScreens.Privacy)} > {lang('PrivacySettings')} onScreenSelect(SettingsScreens.DataStorage)} > {lang('DataSettings')} onScreenSelect(SettingsScreens.Folders)} > {lang('Filters')} onScreenSelect(SettingsScreens.Language)} > {lang('Language')} diff --git a/src/components/left/settings/SettingsNotifications.tsx b/src/components/left/settings/SettingsNotifications.tsx index 880b18055..0b43ca009 100644 --- a/src/components/left/settings/SettingsNotifications.tsx +++ b/src/components/left/settings/SettingsNotifications.tsx @@ -85,12 +85,55 @@ const SettingsNotifications: FC = ({ updateNotificationSettings, ]); + const handleWebNotificationsChange = useCallback((e: ChangeEvent) => { + updateWebNotificationSettings({ + hasWebNotifications: e.target.checked, + }); + }, [updateWebNotificationSettings]); + + const handlePushNotificationsChange = useCallback((e: ChangeEvent) => { + updateWebNotificationSettings({ + hasPushNotifications: e.target.checked, + }); + }, [updateWebNotificationSettings]); + + const handlePrivateChatsNotificationsChange = useCallback((e: ChangeEvent) => { + handleSettingsChange(e, 'contact', 'silent'); + }, [handleSettingsChange]); + + const handlePrivateChatsPreviewChange = useCallback((e: ChangeEvent) => { + handleSettingsChange(e, 'contact', 'showPreviews'); + }, [handleSettingsChange]); + + const handleGroupsNotificationsChange = useCallback((e: ChangeEvent) => { + handleSettingsChange(e, 'group', 'silent'); + }, [handleSettingsChange]); + + const handleGroupsPreviewChange = useCallback((e: ChangeEvent) => { + handleSettingsChange(e, 'group', 'showPreviews'); + }, [handleSettingsChange]); + + const handleChannelsNotificationsChange = useCallback((e: ChangeEvent) => { + handleSettingsChange(e, 'broadcast', 'silent'); + }, [handleSettingsChange]); + + const handleChannelsPreviewChange = useCallback((e: ChangeEvent) => { + handleSettingsChange(e, 'broadcast', 'showPreviews'); + }, [handleSettingsChange]); + const handleContactNotificationChange = useCallback((e: ChangeEvent) => { updateContactSignUpNotification({ isSilent: !e.target.checked, }); }, [updateContactSignUpNotification]); + const handleVolumeChange = useCallback((volume: number) => { + updateWebNotificationSettings({ + notificationSoundVolume: volume, + }); + runDebounced(() => playNotifySound(undefined, volume)); + }, [runDebounced, updateWebNotificationSettings]); + const lang = useLang(); useHistoryBack(isActive, onReset, onScreenSelect, SettingsScreens.Notifications); @@ -106,9 +149,7 @@ const SettingsNotifications: FC = ({ // eslint-disable-next-line max-len subLabel={lang(hasWebNotifications ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')} checked={hasWebNotifications} - onChange={(e) => { - updateWebNotificationSettings({ hasWebNotifications: e.target.checked }); - }} + onChange={handleWebNotificationsChange} /> = ({ // eslint-disable-next-line max-len subLabel={lang(hasPushNotifications ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')} checked={hasPushNotifications} - onChange={(e) => { - updateWebNotificationSettings({ hasPushNotifications: e.target.checked }); - }} + onChange={handlePushNotificationsChange} />
= ({ min={0} max={10} value={notificationSoundVolume} - onChange={(volume) => { - updateWebNotificationSettings({ notificationSoundVolume: volume }); - runDebounced(() => playNotifySound(undefined, volume)); - }} + onChange={handleVolumeChange} />
@@ -143,9 +179,7 @@ const SettingsNotifications: FC = ({ // eslint-disable-next-line max-len subLabel={lang(hasPrivateChatsNotifications ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')} checked={hasPrivateChatsNotifications} - onChange={(e) => { - handleSettingsChange(e, 'contact', 'silent'); - }} + onChange={handlePrivateChatsNotificationsChange} /> = ({ // eslint-disable-next-line max-len subLabel={lang(hasPrivateChatsMessagePreview ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')} checked={hasPrivateChatsMessagePreview} - onChange={(e) => { - handleSettingsChange(e, 'contact', 'showPreviews'); - }} + onChange={handlePrivateChatsPreviewChange} /> @@ -166,18 +198,14 @@ const SettingsNotifications: FC = ({ label={lang('NotificationsForGroups')} subLabel={lang(hasGroupNotifications ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')} checked={hasGroupNotifications} - onChange={(e) => { - handleSettingsChange(e, 'group', 'silent'); - }} + onChange={handleGroupsNotificationsChange} /> { - handleSettingsChange(e, 'group', 'showPreviews'); - }} + onChange={handleGroupsPreviewChange} /> @@ -189,9 +217,7 @@ const SettingsNotifications: FC = ({ // eslint-disable-next-line max-len subLabel={lang(hasBroadcastNotifications ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')} checked={hasBroadcastNotifications} - onChange={(e) => { - handleSettingsChange(e, 'broadcast', 'silent'); - }} + onChange={handleChannelsNotificationsChange} /> = ({ // eslint-disable-next-line max-len subLabel={lang(hasBroadcastMessagePreview ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')} checked={hasBroadcastMessagePreview} - onChange={(e) => { - handleSettingsChange(e, 'broadcast', 'showPreviews'); - }} + onChange={handleChannelsPreviewChange} /> diff --git a/src/components/left/settings/SettingsPrivacy.tsx b/src/components/left/settings/SettingsPrivacy.tsx index 07dc10d49..89a41a02c 100644 --- a/src/components/left/settings/SettingsPrivacy.tsx +++ b/src/components/left/settings/SettingsPrivacy.tsx @@ -84,6 +84,7 @@ const SettingsPrivacy: FC = ({ onScreenSelect(SettingsScreens.PrivacyBlockedUsers)} >
@@ -98,6 +99,7 @@ const SettingsPrivacy: FC = ({ onScreenSelect( hasPassword ? SettingsScreens.TwoFaEnabled : SettingsScreens.TwoFaDisabled, )} @@ -112,6 +114,7 @@ const SettingsPrivacy: FC = ({ onScreenSelect(SettingsScreens.PrivacyActiveSessions)} >
@@ -131,6 +134,7 @@ const SettingsPrivacy: FC = ({ onScreenSelect(SettingsScreens.PrivacyPhoneNumber)} >
@@ -143,6 +147,7 @@ const SettingsPrivacy: FC = ({ onScreenSelect(SettingsScreens.PrivacyLastSeen)} >
@@ -155,6 +160,7 @@ const SettingsPrivacy: FC = ({ onScreenSelect(SettingsScreens.PrivacyProfilePhoto)} >
@@ -167,6 +173,7 @@ const SettingsPrivacy: FC = ({ onScreenSelect(SettingsScreens.PrivacyForwarding)} >
@@ -179,6 +186,7 @@ const SettingsPrivacy: FC = ({ onScreenSelect(SettingsScreens.PrivacyGroupChats)} >
diff --git a/src/components/left/settings/SettingsPrivacyVisibility.tsx b/src/components/left/settings/SettingsPrivacyVisibility.tsx index 90a5f73b8..ce8167557 100644 --- a/src/components/left/settings/SettingsPrivacyVisibility.tsx +++ b/src/components/left/settings/SettingsPrivacyVisibility.tsx @@ -176,6 +176,7 @@ const SettingsPrivacyVisibility: FC = ({ { onScreenSelect(allowedContactsScreen); }} @@ -191,6 +192,7 @@ const SettingsPrivacyVisibility: FC = ({ { onScreenSelect(deniedContactsScreen); }} diff --git a/src/components/left/settings/SettingsStickerSet.tsx b/src/components/left/settings/SettingsStickerSet.tsx index 5d14abf05..97c26aea0 100644 --- a/src/components/left/settings/SettingsStickerSet.tsx +++ b/src/components/left/settings/SettingsStickerSet.tsx @@ -40,6 +40,7 @@ const SettingsStickerSet: FC = ({ narrow className="SettingsStickerSet" inactive={!firstSticker} + // eslint-disable-next-line react/jsx-no-bind onClick={() => firstSticker && onClick(firstSticker)} > +
diff --git a/src/components/main/Dialogs.tsx b/src/components/main/Dialogs.tsx index 7b2a3b382..8182ef528 100644 --- a/src/components/main/Dialogs.tsx +++ b/src/components/main/Dialogs.tsx @@ -96,7 +96,12 @@ const Dialogs: FC = ({ dialogs }) => { : lang('MemberRequests.RequestToJoinDescriptionGroup')}

)} - @@ -122,7 +127,14 @@ const Dialogs: FC = ({ dialogs }) => { > {lang('AreYouSureShareMyContactInfoBot')}
- +
diff --git a/src/components/main/Notifications.tsx b/src/components/main/Notifications.tsx index 706ead00b..097521875 100644 --- a/src/components/main/Notifications.tsx +++ b/src/components/main/Notifications.tsx @@ -24,6 +24,7 @@ const Notifications: FC = ({ notifications }) => { {notifications.map(({ message, localId }) => ( dismissNotification({ localId })} /> ))} diff --git a/src/components/mediaViewer/VideoPlayerControls.tsx b/src/components/mediaViewer/VideoPlayerControls.tsx index ee48b7b76..ebf99f3f8 100644 --- a/src/components/mediaViewer/VideoPlayerControls.tsx +++ b/src/components/mediaViewer/VideoPlayerControls.tsx @@ -220,6 +220,7 @@ const VideoPlayerControls: FC = ({ onClose={closePlaybackMenu} > {PLAYBACK_RATES.map((rate) => ( + // eslint-disable-next-line react/jsx-no-bind onPlaybackRateChange(rate)}> {`${rate}x`} diff --git a/src/components/mediaViewer/ZoomControls.tsx b/src/components/mediaViewer/ZoomControls.tsx index 289eb02ed..963be515d 100644 --- a/src/components/mediaViewer/ZoomControls.tsx +++ b/src/components/mediaViewer/ZoomControls.tsx @@ -36,17 +36,17 @@ const ZoomControls: FC = ({ isShown, onChangeZoom }) => { } }, [isShown, prevIsShown]); - const handleZoomOut = () => { + const handleZoomOut = useCallback(() => { if (inputRef.current) { setZoomLevel(Math.max(MIN_ZOOM_LEVEL, zoomLevel - 0.5)); } - }; + }, [zoomLevel]); - const handleZoomIn = () => { + const handleZoomIn = useCallback(() => { if (inputRef.current) { setZoomLevel(Math.min(MAX_ZOOM_LEVEL, zoomLevel + 0.5)); } - }; + }, [zoomLevel]); const handleStartSeek = useCallback(() => { isSeeking.current = true; diff --git a/src/components/middle/MobileSearch.tsx b/src/components/middle/MobileSearch.tsx index 6ece4e574..b5d2b3830 100644 --- a/src/components/middle/MobileSearch.tsx +++ b/src/components/middle/MobileSearch.tsx @@ -166,6 +166,7 @@ const MobileSearchFooter: FC = ({ round size="smaller" color="translucent" + // eslint-disable-next-line react/jsx-no-bind onClick={() => openHistoryCalendar({ selectedAt: getDayStartAt(Date.now()) })} ariaLabel="Search messages by date" > diff --git a/src/components/middle/ReactorListModal.tsx b/src/components/middle/ReactorListModal.tsx index 857b3bd45..06f3b3535 100644 --- a/src/components/middle/ReactorListModal.tsx +++ b/src/components/middle/ReactorListModal.tsx @@ -124,6 +124,7 @@ const ReactorListModal: FC = ({ className={buildClassName(!chosenTab && 'chosen')} size="tiny" ripple + // eslint-disable-next-line react/jsx-no-bind onClick={() => setChosenTab(undefined)} > @@ -136,6 +137,7 @@ const ReactorListModal: FC = ({ className={buildClassName(chosenTab === reaction && 'chosen')} size="tiny" ripple + // eslint-disable-next-line react/jsx-no-bind onClick={() => setChosenTab(reaction)} > @@ -162,6 +164,7 @@ const ReactorListModal: FC = ({ handleClick(userId)} > diff --git a/src/components/middle/composer/BotCommand.tsx b/src/components/middle/composer/BotCommand.tsx index 1e757e37b..e8df5e994 100644 --- a/src/components/middle/composer/BotCommand.tsx +++ b/src/components/middle/composer/BotCommand.tsx @@ -30,6 +30,7 @@ const BotCommand: FC = ({ key={botCommand.command} className={buildClassName('BotCommand chat-item-clickable scroll-item', withAvatar && 'with-avatar')} multiline + // eslint-disable-next-line react/jsx-no-bind onClick={() => onClick(botCommand)} focus={focus} > diff --git a/src/components/middle/composer/BotKeyboardMenu.tsx b/src/components/middle/composer/BotKeyboardMenu.tsx index 68bf47875..4295bf5e3 100644 --- a/src/components/middle/composer/BotKeyboardMenu.tsx +++ b/src/components/middle/composer/BotKeyboardMenu.tsx @@ -1,4 +1,6 @@ -import React, { FC, memo, useEffect } from '../../../lib/teact/teact'; +import React, { + FC, memo, useCallback, useEffect, +} from '../../../lib/teact/teact'; import { getActions, withGlobal } from '../../../global'; import { ApiMessage } from '../../../api/types'; @@ -32,10 +34,10 @@ const BotKeyboardMenu: FC = ({ const { isKeyboardSingleUse } = message || {}; const [forceOpen, markForceOpen, unmarkForceOpen] = useFlag(true); - const handleClose = () => { + const handleClose = useCallback(() => { unmarkForceOpen(); onClose(); - }; + }, [onClose, unmarkForceOpen]); useEffect(() => { markForceOpen(); @@ -65,6 +67,7 @@ const BotKeyboardMenu: FC = ({