diff --git a/src/components/middle/composer/CustomEmojiTooltip.tsx b/src/components/middle/composer/CustomEmojiTooltip.tsx index e39f2aa17..3afd258af 100644 --- a/src/components/middle/composer/CustomEmojiTooltip.tsx +++ b/src/components/middle/composer/CustomEmojiTooltip.tsx @@ -5,7 +5,7 @@ import { getActions, withGlobal } from '../../../global'; import type { FC } from '../../../lib/teact/teact'; import type { ApiSticker } from '../../../api/types'; -import type { GlobalActions } from '../../../global/types'; +import type { GlobalActions } from '../../../global'; import { COMPOSER_EMOJI_SIZE_PICKER } from '../../../config'; import { selectIsChatWithSelf, selectIsCurrentUserPremium } from '../../../global/selectors'; diff --git a/src/components/middle/composer/SymbolMenu.tsx b/src/components/middle/composer/SymbolMenu.tsx index cbc8f08b8..66d9d9373 100644 --- a/src/components/middle/composer/SymbolMenu.tsx +++ b/src/components/middle/composer/SymbolMenu.tsx @@ -5,7 +5,7 @@ import { getActions, withGlobal } from '../../../global'; import type { FC } from '../../../lib/teact/teact'; import type { ApiSticker, ApiVideo } from '../../../api/types'; -import type { GlobalActions } from '../../../global/types'; +import type { GlobalActions } from '../../../global'; import { IS_TOUCH_ENV } from '../../../util/environment'; import { fastRaf } from '../../../util/schedulers'; diff --git a/src/global/actions/ui/messages.ts b/src/global/actions/ui/messages.ts index 1c6bb20a8..791d04e4b 100644 --- a/src/global/actions/ui/messages.ts +++ b/src/global/actions/ui/messages.ts @@ -810,7 +810,7 @@ addActionHandler('closeMessageLanguageModal', (global, actions, payload): Action }); addActionHandler('copySelectedMessages', (global, actions, payload): ActionReturnType => { - const { tabId = getCurrentTabId() } = payload; + const { tabId = getCurrentTabId() } = payload || {}; const tabState = selectTabState(global, tabId); if (!tabState.selectedMessages) { return; diff --git a/src/global/index.ts b/src/global/index.ts index 2c8a6a34a..519bb0573 100644 --- a/src/global/index.ts +++ b/src/global/index.ts @@ -1,7 +1,7 @@ import type { ActionOptions } from '../lib/teact/teactn'; import { typify } from '../lib/teact/teactn'; import type { - GlobalState, ActionPayloads, RequiredGlobalState, RequiredActionPayloads, + GlobalState, ActionPayloads, RequiredActionPayloads, RequiredGlobalState, } from './types'; const typed = typify(); @@ -46,3 +46,4 @@ export const addActionHandler = typed.addActionHandler as void; export const withGlobal = typed.withGlobal; +export type GlobalActions = ReturnType; diff --git a/src/global/types.ts b/src/global/types.ts index 5a6be8536..db7296f4a 100644 --- a/src/global/types.ts +++ b/src/global/types.ts @@ -1,92 +1,92 @@ import type { + ApiAppConfig, + ApiAttachBot, + ApiAttachment, + ApiAvailableReaction, + ApiChannelStatistics, ApiChat, + ApiChatAdminRights, + ApiChatBannedRights, + ApiChatFolder, + ApiChatReactions, + ApiChatType, + ApiConfig, + ApiContact, + ApiCountry, + ApiCountryCode, + ApiError, + ApiExportedInvite, + ApiFormattedText, + ApiGlobalMessageSearchType, + ApiGroupCall, + ApiGroupStatistics, + ApiInputInvoice, + ApiInviteInfo, + ApiInvoice, + ApiKeyboardButton, ApiMessage, + ApiMessageEntity, + ApiMessageStatistics, + ApiNewPoll, + ApiNotification, + ApiPaymentCredentials, + ApiPaymentFormNativeParams, + ApiPaymentSavedInfo, + ApiPhoneCall, + ApiPhoto, + ApiPremiumPromo, + ApiReaction, + ApiReceipt, + ApiReportReason, + ApiSendMessageAction, + ApiSession, + ApiSessionData, + ApiSponsoredMessage, + ApiSticker, + ApiStickerSet, + ApiStickerSetInfo, + ApiThemeParameters, ApiThreadInfo, - ApiUser, - ApiUserStatus, + ApiTranscription, + ApiTypingStatus, + ApiUpdate, ApiUpdateAuthorizationStateType, ApiUpdateConnectionStateType, - ApiStickerSet, - ApiSticker, - ApiWebPage, + ApiUser, + ApiUserStatus, ApiVideo, - ApiFormattedText, - ApiChatFolder, ApiWallpaper, - ApiNotification, - ApiError, - ApiGlobalMessageSearchType, - ApiPaymentSavedInfo, - ApiSession, - ApiNewPoll, - ApiInviteInfo, - ApiCountryCode, - ApiCountry, - ApiGroupCall, - ApiAvailableReaction, - ApiAppConfig, - ApiSponsoredMessage, - ApiChannelStatistics, - ApiGroupStatistics, - ApiMessageStatistics, - ApiPaymentFormNativeParams, - ApiUpdate, - ApiReportReason, - ApiPhoto, - ApiKeyboardButton, - ApiThemeParameters, - ApiAttachBot, - ApiPhoneCall, + ApiWebPage, ApiWebSession, - ApiPremiumPromo, - ApiTranscription, - ApiInputInvoice, - ApiInvoice, - ApiStickerSetInfo, - ApiChatType, - ApiReceipt, - ApiPaymentCredentials, - ApiConfig, - ApiReaction, - ApiChatReactions, - ApiContact, - ApiExportedInvite, - ApiSendMessageAction, - ApiMessageEntity, - ApiAttachment, - ApiChatBannedRights, - ApiChatAdminRights, - ApiSessionData, - ApiTypingStatus, } from '../api/types'; import type { - FocusDirection, - ISettings, - MediaViewerOrigin, - ChatCreationProgress, - ProfileEditProgress, - SharedMediaType, - GlobalSearchContent, - ManagementProgress, - PaymentStep, - ShippingOption, ApiInvoiceContainer, ApiPrivacyKey, ApiPrivacySettings, - ThemeKey, - IThemeSettings, - NotifyException, - LangCode, - EmojiKeywords, - InlineBotSettings, - NewChatMembersProgress, AudioOrigin, - ManagementState, - SettingsScreens, + ChatCreationProgress, + EmojiKeywords, + FocusDirection, + GlobalSearchContent, + InlineBotSettings, + ISettings, + IThemeSettings, + LangCode, + LoadMoreDirection, + ManagementProgress, ManagementScreens, - LoadMoreDirection, PrivacyVisibility, + ManagementState, + MediaViewerOrigin, + NewChatMembersProgress, + NotifyException, + PaymentStep, + PrivacyVisibility, + ProfileEditProgress, + SettingsScreens, + SharedMediaType, + ShippingOption, + ThemeKey, } from '../types'; -import { typify } from '../lib/teact/teactn'; import type { P2pMessage } from '../lib/secret-sauce'; import type { ApiCredentials } from '../components/payment/PaymentModal'; @@ -1364,7 +1364,7 @@ export interface ActionPayloads { }; resetLeftColumnWidth: undefined; - copySelectedMessages: WithTabId; + copySelectedMessages: WithTabId | undefined; copyMessagesByIds: { messageIds?: number[]; } & WithTabId; @@ -2064,7 +2064,7 @@ export interface ActionPayloads { loadAttachBots: { hash?: string; - }; + } | undefined; toggleAttachBot: { botId: string; @@ -2129,9 +2129,9 @@ export interface ActionPayloads { }; // Misc - openPollModal: { + openPollModal: ({ isQuiz?: boolean; - } & WithTabId; + } & WithTabId) | undefined; closePollModal: WithTabId | undefined; requestConfetti: ({ top: number; @@ -2183,7 +2183,7 @@ export interface ActionPayloads { toggleGroupCallMute: { participantId: string; value: boolean; - }; + } | undefined; toggleGroupCallPresentation: { value?: boolean; } | undefined; @@ -2263,14 +2263,14 @@ export interface ActionPayloads { updateGlobalPrivacySettings: { shouldArchiveAndMuteNewNonContact: boolean }; // Premium - openPremiumModal: { + openPremiumModal: ({ initialSection?: string; fromUserId?: string; toUserId?: string; isSuccess?: boolean; isGift?: boolean; monthsAmount?: number; - } & WithTabId; + } & WithTabId) | undefined; closePremiumModal: ({ isClosed?: boolean; } & WithTabId) | undefined; @@ -2281,11 +2281,11 @@ export interface ActionPayloads { }; loadPremiumGifts: undefined; - loadDefaultTopicIcons: never; + loadDefaultTopicIcons: undefined; loadPremiumStickers: undefined; loadPremiumSetStickers: { hash?: string; - }; + } | undefined; openGiftPremiumModal: ({ forUserId?: string; @@ -2379,8 +2379,6 @@ export interface ActionPayloads { } export type RequiredGlobalState = GlobalState & { _: never }; -const typed = typify(); -export type GlobalActions = ReturnType; export type ActionReturnType = GlobalState | void | Promise; export type TabArgs = T extends RequiredGlobalState ? [ tabId: number, diff --git a/src/lib/teact/teactn.tsx b/src/lib/teact/teactn.tsx index a02798f25..f0da4eda4 100644 --- a/src/lib/teact/teactn.tsx +++ b/src/lib/teact/teactn.tsx @@ -300,11 +300,14 @@ export function typify< >() { type ProjectActionNames = keyof ActionPayloads; + // When payload is allowed to be `undefined` we consider it optional type ProjectActions = { - [ActionName in ProjectActionNames]: ( - payload?: ActionPayloads[ActionName], - options?: ActionOptions, - ) => void; + [ActionName in ProjectActionNames]: + (undefined extends ActionPayloads[ActionName] ? ( + (payload?: ActionPayloads[ActionName], options?: ActionOptions) => void + ) : ( + (payload: ActionPayloads[ActionName], options?: ActionOptions) => void + )) }; type ActionHandlers = { diff --git a/src/util/requestActionTimeout.ts b/src/util/requestActionTimeout.ts index 8d16c4e82..8894bcfd3 100644 --- a/src/util/requestActionTimeout.ts +++ b/src/util/requestActionTimeout.ts @@ -1,12 +1,12 @@ +import type { GlobalActions } from '../global'; import { getActions } from '../global'; -import type { GlobalActions } from '../global/types'; const callbacks = new Map(); export default function requestActionTimeout(action: keyof GlobalActions, timeout: number) { clearTimeout(callbacks.get(action)); const timerId = window.setTimeout(() => { - getActions()[action](); + (getActions()[action] as VoidFunction)(); }, timeout); callbacks.set(action, timerId); }