[Refactoring] Simplify modal registration (#4501)
This commit is contained in:
parent
209564ca6f
commit
19e90c8fbb
@ -9,10 +9,8 @@ import { addExtraClass } from '../../lib/teact/teact-dom';
|
||||
import { getActions, getGlobal, withGlobal } from '../../global';
|
||||
|
||||
import type {
|
||||
ApiAttachBot,
|
||||
ApiChat,
|
||||
ApiChatFolder,
|
||||
ApiGeoPoint,
|
||||
ApiMessage,
|
||||
ApiUser,
|
||||
} from '../../api/types';
|
||||
@ -24,7 +22,6 @@ import {
|
||||
BASE_EMOJI_KEYWORD_LANG, DEBUG, INACTIVE_MARKER,
|
||||
} from '../../config';
|
||||
import { requestNextMutation } from '../../lib/fasterdom/fasterdom';
|
||||
import { getUserFullName } from '../../global/helpers';
|
||||
import {
|
||||
selectCanAnimateInterface,
|
||||
selectChatFolder,
|
||||
@ -75,15 +72,7 @@ import AudioPlayer from '../middle/AudioPlayer';
|
||||
import ReactionPicker from '../middle/message/reactions/ReactionPicker.async';
|
||||
import MessageListHistoryHandler from '../middle/MessageListHistoryHandler';
|
||||
import MiddleColumn from '../middle/MiddleColumn';
|
||||
import AttachBotInstallModal from '../modals/attachBotInstall/AttachBotInstallModal.async';
|
||||
import BoostModal from '../modals/boost/BoostModal.async';
|
||||
import ChatlistModal from '../modals/chatlist/ChatlistModal.async';
|
||||
import GiftCodeModal from '../modals/giftcode/GiftCodeModal.async';
|
||||
import InviteViaLinkModal from '../modals/inviteViaLink/InviteViaLinkModal.async';
|
||||
import MapModal from '../modals/map/MapModal.async';
|
||||
import OneTimeMediaModal from '../modals/oneTimeMedia/OneTimeMediaModal.async';
|
||||
import UrlAuthModal from '../modals/urlAuth/UrlAuthModal.async';
|
||||
import WebAppModal from '../modals/webApp/WebAppModal.async';
|
||||
import ModalContainer from '../modals/ModalContainer';
|
||||
import PaymentModal from '../payment/PaymentModal.async';
|
||||
import ReceiptModal from '../payment/ReceiptModal.async';
|
||||
import RightColumn from '../right/RightColumn';
|
||||
@ -126,8 +115,6 @@ type StateProps = {
|
||||
hasDialogs: boolean;
|
||||
audioMessage?: ApiMessage;
|
||||
safeLinkModalUrl?: string;
|
||||
mapModalGeoPoint?: ApiGeoPoint;
|
||||
mapModalZoom?: number;
|
||||
isHistoryCalendarOpen: boolean;
|
||||
shouldSkipHistoryAnimations?: boolean;
|
||||
openedStickerSetShortName?: string;
|
||||
@ -144,15 +131,11 @@ type StateProps = {
|
||||
openedGame?: TabState['openedGame'];
|
||||
gameTitle?: string;
|
||||
isRatePhoneCallModalOpen?: boolean;
|
||||
webApp?: TabState['webApp'];
|
||||
isPremiumModalOpen?: boolean;
|
||||
botTrustRequest?: TabState['botTrustRequest'];
|
||||
botTrustRequestBot?: ApiUser;
|
||||
attachBotToInstall?: ApiAttachBot;
|
||||
requestedAttachBotInChat?: TabState['requestedAttachBotInChat'];
|
||||
requestedDraft?: TabState['requestedDraft'];
|
||||
currentUserName?: string;
|
||||
urlAuth?: TabState['urlAuth'];
|
||||
limitReached?: ApiLimitTypeWithModal;
|
||||
deleteFolderDialog?: ApiChatFolder;
|
||||
isPaymentModalOpen?: boolean;
|
||||
@ -162,14 +145,9 @@ type StateProps = {
|
||||
isGiveawayModalOpen?: boolean;
|
||||
isPremiumGiftingModalOpen?: boolean;
|
||||
isCurrentUserPremium?: boolean;
|
||||
chatlistModal?: TabState['chatlistModal'];
|
||||
boostModal?: TabState['boostModal'];
|
||||
giftCodeModal?: TabState['giftCodeModal'];
|
||||
noRightColumnAnimation?: boolean;
|
||||
withInterfaceAnimations?: boolean;
|
||||
isSynced?: boolean;
|
||||
inviteViaLinkModal?: TabState['inviteViaLinkModal'];
|
||||
oneTimeMediaModal?: TabState['oneTimeMediaModal'];
|
||||
};
|
||||
|
||||
const APP_OUTDATED_TIMEOUT_MS = 5 * 60 * 1000; // 5 min
|
||||
@ -191,8 +169,6 @@ const Main: FC<OwnProps & StateProps> = ({
|
||||
audioMessage,
|
||||
activeGroupCallId,
|
||||
safeLinkModalUrl,
|
||||
mapModalGeoPoint,
|
||||
mapModalZoom,
|
||||
isHistoryCalendarOpen,
|
||||
shouldSkipHistoryAnimations,
|
||||
limitReached,
|
||||
@ -212,12 +188,8 @@ const Main: FC<OwnProps & StateProps> = ({
|
||||
isRatePhoneCallModalOpen,
|
||||
botTrustRequest,
|
||||
botTrustRequestBot,
|
||||
attachBotToInstall,
|
||||
requestedAttachBotInChat,
|
||||
requestedDraft,
|
||||
webApp,
|
||||
currentUserName,
|
||||
urlAuth,
|
||||
isPremiumModalOpen,
|
||||
isGiveawayModalOpen,
|
||||
isPremiumGiftingModalOpen,
|
||||
@ -227,13 +199,8 @@ const Main: FC<OwnProps & StateProps> = ({
|
||||
isCurrentUserPremium,
|
||||
deleteFolderDialog,
|
||||
isMasterTab,
|
||||
chatlistModal,
|
||||
giftCodeModal,
|
||||
boostModal,
|
||||
noRightColumnAnimation,
|
||||
isSynced,
|
||||
inviteViaLinkModal,
|
||||
oneTimeMediaModal,
|
||||
currentUserId,
|
||||
}) => {
|
||||
const {
|
||||
@ -565,9 +532,8 @@ const Main: FC<OwnProps & StateProps> = ({
|
||||
<Notifications isOpen={hasNotifications} />
|
||||
<Dialogs isOpen={hasDialogs} />
|
||||
{audioMessage && <AudioPlayer key={audioMessage.id} message={audioMessage} noUi />}
|
||||
<ModalContainer />
|
||||
<SafeLinkModal url={safeLinkModalUrl} />
|
||||
<MapModal geoPoint={mapModalGeoPoint} zoom={mapModalZoom} />
|
||||
<UrlAuthModal urlAuth={urlAuth} currentUserName={currentUserName} />
|
||||
<HistoryCalendar isOpen={isHistoryCalendarOpen} />
|
||||
<StickerSetModal
|
||||
isOpen={Boolean(openedStickerSetShortName)}
|
||||
@ -585,12 +551,7 @@ const Main: FC<OwnProps & StateProps> = ({
|
||||
userId={newContactUserId}
|
||||
isByPhoneNumber={newContactByPhoneNumber}
|
||||
/>
|
||||
<BoostModal info={boostModal} />
|
||||
<GiftCodeModal modal={giftCodeModal} />
|
||||
<OneTimeMediaModal info={oneTimeMediaModal} />
|
||||
<ChatlistModal info={chatlistModal} />
|
||||
<GameModal openedGame={openedGame} gameTitle={gameTitle} />
|
||||
<WebAppModal webApp={webApp} />
|
||||
<DownloadManager />
|
||||
<ConfettiContainer />
|
||||
<PhoneCall isActive={isPhoneCallActive} />
|
||||
@ -601,7 +562,6 @@ const Main: FC<OwnProps & StateProps> = ({
|
||||
type={botTrustRequest?.type}
|
||||
shouldRequestWriteAccess={botTrustRequest?.shouldRequestWriteAccess}
|
||||
/>
|
||||
<AttachBotInstallModal bot={attachBotToInstall} />
|
||||
<AttachBotRecipientPicker requestedAttachBotInChat={requestedAttachBotInChat} />
|
||||
<MessageListHistoryHandler />
|
||||
{isPremiumModalOpen && <PremiumMainModal isOpen={isPremiumModalOpen} />}
|
||||
@ -612,7 +572,6 @@ const Main: FC<OwnProps & StateProps> = ({
|
||||
<ReceiptModal isOpen={isReceiptModalOpen} onClose={clearReceipt} />
|
||||
<DeleteFolderDialog folder={deleteFolderDialog} />
|
||||
<ReactionPicker isOpen={isReactionPickerOpen} />
|
||||
<InviteViaLinkModal missingUsers={inviteViaLinkModal?.missingUsers} chatId={inviteViaLinkModal?.chatId} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -630,13 +589,9 @@ export default memo(withGlobal<OwnProps>(
|
||||
|
||||
const {
|
||||
botTrustRequest,
|
||||
requestedAttachBotInstall,
|
||||
requestedAttachBotInChat,
|
||||
requestedDraft,
|
||||
urlAuth,
|
||||
webApp,
|
||||
safeLinkModalUrl,
|
||||
mapModal,
|
||||
openedStickerSetShortName,
|
||||
openedCustomEmojiSetIds,
|
||||
shouldSkipHistoryAnimations,
|
||||
@ -655,11 +610,6 @@ export default memo(withGlobal<OwnProps>(
|
||||
payment,
|
||||
limitReachedModal,
|
||||
deleteFolderDialogModal,
|
||||
chatlistModal,
|
||||
boostModal,
|
||||
giftCodeModal,
|
||||
inviteViaLinkModal,
|
||||
oneTimeMediaModal,
|
||||
} = selectTabState(global);
|
||||
|
||||
const { chatId: audioChatId, messageId: audioMessageId } = audioPlayer;
|
||||
@ -668,7 +618,6 @@ export default memo(withGlobal<OwnProps>(
|
||||
: undefined;
|
||||
const gameMessage = openedGame && selectChatMessage(global, openedGame.chatId, openedGame.messageId);
|
||||
const gameTitle = gameMessage?.content.game?.title;
|
||||
const currentUser = global.currentUserId ? selectUser(global, global.currentUserId) : undefined;
|
||||
const { chatId } = selectCurrentMessageList(global) || {};
|
||||
const noRightColumnAnimation = !selectPerformanceSettingsValue(global, 'rightColumnAnimations')
|
||||
|| !selectCanAnimateInterface(global);
|
||||
@ -688,8 +637,6 @@ export default memo(withGlobal<OwnProps>(
|
||||
hasDialogs: Boolean(dialogs.length),
|
||||
audioMessage,
|
||||
safeLinkModalUrl,
|
||||
mapModalGeoPoint: mapModal?.point,
|
||||
mapModalZoom: mapModal?.zoom,
|
||||
isHistoryCalendarOpen: Boolean(historyCalendarSelectedAt),
|
||||
shouldSkipHistoryAnimations,
|
||||
openedStickerSetShortName,
|
||||
@ -709,11 +656,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
isRatePhoneCallModalOpen: Boolean(ratingPhoneCall),
|
||||
botTrustRequest,
|
||||
botTrustRequestBot: botTrustRequest && selectUser(global, botTrustRequest.botId),
|
||||
attachBotToInstall: requestedAttachBotInstall?.bot,
|
||||
requestedAttachBotInChat,
|
||||
webApp,
|
||||
currentUserName: getUserFullName(currentUser),
|
||||
urlAuth,
|
||||
isCurrentUserPremium: selectIsCurrentUserPremium(global),
|
||||
isPremiumModalOpen: premiumModal?.isOpen,
|
||||
isGiveawayModalOpen: giveawayModal?.isOpen,
|
||||
@ -724,13 +667,8 @@ export default memo(withGlobal<OwnProps>(
|
||||
deleteFolderDialog,
|
||||
isMasterTab,
|
||||
requestedDraft,
|
||||
chatlistModal,
|
||||
boostModal,
|
||||
giftCodeModal,
|
||||
noRightColumnAnimation,
|
||||
isSynced: global.isSynced,
|
||||
inviteViaLinkModal,
|
||||
oneTimeMediaModal,
|
||||
};
|
||||
},
|
||||
)(Main));
|
||||
|
||||
66
src/components/modals/ModalContainer.tsx
Normal file
66
src/components/modals/ModalContainer.tsx
Normal file
@ -0,0 +1,66 @@
|
||||
import React, { memo } from '../../lib/teact/teact';
|
||||
import { withGlobal } from '../../global';
|
||||
|
||||
import type { TabState } from '../../global/types';
|
||||
|
||||
import { selectTabState } from '../../global/selectors';
|
||||
import { pick } from '../../util/iteratees';
|
||||
|
||||
import AttachBotInstallModal from './attachBotInstall/AttachBotInstallModal.async';
|
||||
import BoostModal from './boost/BoostModal.async';
|
||||
import ChatlistModal from './chatlist/ChatlistModal.async';
|
||||
import GiftCodeModal from './giftcode/GiftCodeModal.async';
|
||||
import InviteViaLinkModal from './inviteViaLink/InviteViaLinkModal.async';
|
||||
import OneTimeMediaModal from './oneTimeMedia/OneTimeMediaModal.async';
|
||||
import UrlAuthModal from './urlAuth/UrlAuthModal.async';
|
||||
import WebAppModal from './webApp/WebAppModal.async';
|
||||
|
||||
// `Pick` used only to provide tab completion
|
||||
type ModalKey = keyof Pick<TabState,
|
||||
'giftCodeModal' |
|
||||
'boostModal' |
|
||||
'chatlistModal' |
|
||||
'urlAuth' |
|
||||
'oneTimeMediaModal' |
|
||||
'inviteViaLinkModal' |
|
||||
'requestedAttachBotInstall' |
|
||||
'webApp'
|
||||
>;
|
||||
|
||||
type StateProps = {
|
||||
[K in ModalKey]?: TabState[K];
|
||||
};
|
||||
type ModalRegistry = {
|
||||
[K in ModalKey]: React.FC<{
|
||||
modal: TabState[K];
|
||||
}>;
|
||||
};
|
||||
type Entries<T> = {
|
||||
[K in keyof T]: [K, T[K]];
|
||||
}[keyof T][];
|
||||
|
||||
const MODALS: ModalRegistry = {
|
||||
giftCodeModal: GiftCodeModal,
|
||||
boostModal: BoostModal,
|
||||
chatlistModal: ChatlistModal,
|
||||
urlAuth: UrlAuthModal,
|
||||
oneTimeMediaModal: OneTimeMediaModal,
|
||||
inviteViaLinkModal: InviteViaLinkModal,
|
||||
requestedAttachBotInstall: AttachBotInstallModal,
|
||||
webApp: WebAppModal,
|
||||
};
|
||||
const MODAL_KEYS = Object.keys(MODALS) as ModalKey[];
|
||||
const MODAL_ENTRIES = Object.entries(MODALS) as Entries<ModalRegistry>;
|
||||
|
||||
const ModalContainer = (modalProps: StateProps) => {
|
||||
return MODAL_ENTRIES.map(([key, ModalComponent]) => (
|
||||
// @ts-ignore -- TS does not preserve tuple types in `map` callbacks
|
||||
<ModalComponent key={key} modal={modalProps[key]} />
|
||||
));
|
||||
};
|
||||
|
||||
export default memo(withGlobal(
|
||||
(global): StateProps => (
|
||||
pick(selectTabState(global), MODAL_KEYS)
|
||||
),
|
||||
)(ModalContainer));
|
||||
@ -8,8 +8,8 @@ import { Bundles } from '../../../util/moduleLoader';
|
||||
import useModuleLoader from '../../../hooks/useModuleLoader';
|
||||
|
||||
const AttachBotInstallModalAsync: FC<OwnProps> = (props) => {
|
||||
const { bot } = props;
|
||||
const AttachBotInstallModal = useModuleLoader(Bundles.Extra, 'AttachBotInstallModal', !bot);
|
||||
const { modal } = props;
|
||||
const AttachBotInstallModal = useModuleLoader(Bundles.Extra, 'AttachBotInstallModal', !modal);
|
||||
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
return AttachBotInstallModal ? <AttachBotInstallModal {...props} /> : undefined;
|
||||
|
||||
@ -4,7 +4,7 @@ import React, {
|
||||
} from '../../../lib/teact/teact';
|
||||
import { getActions } from '../../../global';
|
||||
|
||||
import type { ApiAttachBot } from '../../../api/types';
|
||||
import type { TabState } from '../../../global/types';
|
||||
|
||||
import { MINI_APP_TOS_URL } from '../../../config';
|
||||
import renderText from '../../common/helpers/renderText';
|
||||
@ -15,13 +15,15 @@ import Checkbox from '../../ui/Checkbox';
|
||||
import ConfirmDialog from '../../ui/ConfirmDialog';
|
||||
|
||||
export type OwnProps = {
|
||||
bot?: ApiAttachBot;
|
||||
modal: TabState['requestedAttachBotInstall'];
|
||||
};
|
||||
|
||||
const AttachBotInstallModal: FC<OwnProps> = ({
|
||||
bot,
|
||||
modal,
|
||||
}) => {
|
||||
const { confirmAttachBotInstall, cancelAttachBotInstall } = getActions();
|
||||
const bot = modal?.bot;
|
||||
|
||||
const [isTosAccepted, setIsTosAccepted] = useState(false);
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
@ -8,8 +8,8 @@ import { Bundles } from '../../../util/moduleLoader';
|
||||
import useModuleLoader from '../../../hooks/useModuleLoader';
|
||||
|
||||
const BoostModalAsync: FC<OwnProps> = (props) => {
|
||||
const { info } = props;
|
||||
const BoostModal = useModuleLoader(Bundles.Extra, 'BoostModal', !info);
|
||||
const { modal } = props;
|
||||
const BoostModal = useModuleLoader(Bundles.Extra, 'BoostModal', !modal);
|
||||
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
return BoostModal ? <BoostModal {...props} /> : undefined;
|
||||
|
||||
@ -46,7 +46,7 @@ type BoostInfo = ({
|
||||
} & LoadedParams);
|
||||
|
||||
export type OwnProps = {
|
||||
info: TabState['boostModal'];
|
||||
modal: TabState['boostModal'];
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
@ -57,7 +57,7 @@ type StateProps = {
|
||||
};
|
||||
|
||||
const BoostModal = ({
|
||||
info,
|
||||
modal,
|
||||
chat,
|
||||
chatFullInfo,
|
||||
prevBoostedChat,
|
||||
@ -77,7 +77,7 @@ const BoostModal = ({
|
||||
|
||||
const isChannel = chat && isChatChannel(chat);
|
||||
|
||||
const isOpen = Boolean(info);
|
||||
const isOpen = Boolean(modal);
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
@ -115,7 +115,7 @@ const BoostModal = ({
|
||||
descriptionText,
|
||||
canBoostMore,
|
||||
}: BoostInfo = useMemo(() => {
|
||||
if (!info?.boostStatus || !chat) {
|
||||
if (!modal?.boostStatus || !chat) {
|
||||
return {
|
||||
isStatusLoaded: false,
|
||||
title: lang('Loading'),
|
||||
@ -124,10 +124,10 @@ const BoostModal = ({
|
||||
|
||||
const {
|
||||
hasMyBoost,
|
||||
} = info.boostStatus;
|
||||
} = modal.boostStatus;
|
||||
|
||||
const firstBoost = info?.myBoosts && getFirstAvailableBoost(info.myBoosts, chat.id);
|
||||
const areBoostsInDifferentChannels = info?.myBoosts && !areAllBoostsInChannel(info.myBoosts, chat.id);
|
||||
const firstBoost = modal?.myBoosts && getFirstAvailableBoost(modal.myBoosts, chat.id);
|
||||
const areBoostsInDifferentChannels = modal?.myBoosts && !areAllBoostsInChannel(modal.myBoosts, chat.id);
|
||||
|
||||
const {
|
||||
boosts,
|
||||
@ -136,7 +136,7 @@ const BoostModal = ({
|
||||
levelProgress,
|
||||
remainingBoosts,
|
||||
isMaxLevel,
|
||||
} = getBoostProgressInfo(info.boostStatus, true);
|
||||
} = getBoostProgressInfo(modal.boostStatus, true);
|
||||
|
||||
const hasBoost = hasMyBoost;
|
||||
|
||||
@ -172,10 +172,10 @@ const BoostModal = ({
|
||||
isBoosted: hasBoost,
|
||||
canBoostMore: areBoostsInDifferentChannels && !isMaxLevel,
|
||||
};
|
||||
}, [chat, chatTitle, info, lang, chatFullInfo, isChannel]);
|
||||
}, [chat, chatTitle, modal, lang, chatFullInfo, isChannel]);
|
||||
|
||||
const isBoostDisabled = !info?.myBoosts?.length && isCurrentUserPremium;
|
||||
const isReplacingBoost = boost?.chatId && boost.chatId !== info?.chatId;
|
||||
const isBoostDisabled = !modal?.myBoosts?.length && isCurrentUserPremium;
|
||||
const isReplacingBoost = boost?.chatId && boost.chatId !== modal?.chatId;
|
||||
|
||||
const handleApplyBoost = useLastCallback(() => {
|
||||
closeReplaceModal();
|
||||
@ -342,10 +342,10 @@ function areAllBoostsInChannel(myBoosts: ApiMyBoost[], chatId: string) {
|
||||
}
|
||||
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global, { info }): StateProps => {
|
||||
const chat = info && selectChat(global, info?.chatId);
|
||||
(global, { modal }): StateProps => {
|
||||
const chat = modal && selectChat(global, modal?.chatId);
|
||||
const chatFullInfo = chat && selectChatFullInfo(global, chat.id);
|
||||
const firstBoost = info?.myBoosts && getFirstAvailableBoost(info.myBoosts, info.chatId);
|
||||
const firstBoost = modal?.myBoosts && getFirstAvailableBoost(modal.myBoosts, modal.chatId);
|
||||
const boostedChat = firstBoost?.chatId ? selectChat(global, firstBoost?.chatId) : undefined;
|
||||
|
||||
return {
|
||||
|
||||
@ -8,8 +8,8 @@ import { Bundles } from '../../../util/moduleLoader';
|
||||
import useModuleLoader from '../../../hooks/useModuleLoader';
|
||||
|
||||
const ChatlistModalAsync: FC<OwnProps> = (props) => {
|
||||
const { info } = props;
|
||||
const ChatlistModal = useModuleLoader(Bundles.Extra, 'ChatlistModal', !info);
|
||||
const { modal } = props;
|
||||
const ChatlistModal = useModuleLoader(Bundles.Extra, 'ChatlistModal', !modal);
|
||||
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
return ChatlistModal ? <ChatlistModal {...props} /> : undefined;
|
||||
|
||||
@ -19,7 +19,7 @@ import ChatlistNew from './ChatlistNew';
|
||||
import styles from './ChatlistModal.module.scss';
|
||||
|
||||
export type OwnProps = {
|
||||
info?: TabState['chatlistModal'];
|
||||
modal?: TabState['chatlistModal'];
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
@ -27,15 +27,15 @@ type StateProps = {
|
||||
};
|
||||
|
||||
const ChatlistInviteModal: FC<OwnProps & StateProps> = ({
|
||||
info,
|
||||
modal,
|
||||
folder,
|
||||
}) => {
|
||||
const { closeChatlistModal } = getActions();
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
const isOpen = Boolean(info);
|
||||
const renderingInfo = usePrevious(info) || info;
|
||||
const isOpen = Boolean(modal);
|
||||
const renderingInfo = usePrevious(modal) || modal;
|
||||
const renderingFolder = usePrevious(folder) || folder;
|
||||
|
||||
const title = useMemo(() => {
|
||||
@ -111,8 +111,8 @@ const ChatlistInviteModal: FC<OwnProps & StateProps> = ({
|
||||
};
|
||||
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global, { info }): StateProps => {
|
||||
const { invite, removal } = info || {};
|
||||
(global, { modal }): StateProps => {
|
||||
const { invite, removal } = modal || {};
|
||||
const folderId = removal?.folderId || (invite && 'folderId' in invite ? invite.folderId : undefined);
|
||||
const folder = folderId ? selectChatFolder(global, folderId) : undefined;
|
||||
|
||||
|
||||
@ -8,8 +8,8 @@ import { Bundles } from '../../../util/moduleLoader';
|
||||
import useModuleLoader from '../../../hooks/useModuleLoader';
|
||||
|
||||
const InviteViaLinkModalAsync: FC<OwnProps> = (props) => {
|
||||
const { chatId } = props;
|
||||
const InviteViaLinkModal = useModuleLoader(Bundles.Extra, 'InviteViaLinkModal', !chatId);
|
||||
const { modal } = props;
|
||||
const InviteViaLinkModal = useModuleLoader(Bundles.Extra, 'InviteViaLinkModal', !modal);
|
||||
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
return InviteViaLinkModal ? <InviteViaLinkModal {...props} /> : undefined;
|
||||
|
||||
@ -6,7 +6,8 @@ import React, {
|
||||
} from '../../../lib/teact/teact';
|
||||
import { getActions, getGlobal, withGlobal } from '../../../global';
|
||||
|
||||
import type { ApiChat, ApiMissingInvitedUser } from '../../../api/types';
|
||||
import type { ApiChat } from '../../../api/types';
|
||||
import type { TabState } from '../../../global/types';
|
||||
|
||||
import { getUserFullName } from '../../../global/helpers';
|
||||
import { selectChat } from '../../../global/selectors';
|
||||
@ -25,8 +26,7 @@ import Separator from '../../ui/Separator';
|
||||
import styles from './InviteViaLinkModal.module.scss';
|
||||
|
||||
export type OwnProps = {
|
||||
chatId?: string;
|
||||
missingUsers?: ApiMissingInvitedUser[];
|
||||
modal: TabState['inviteViaLinkModal'];
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
@ -34,10 +34,11 @@ type StateProps = {
|
||||
};
|
||||
|
||||
const InviteViaLinkModal: FC<OwnProps & StateProps> = ({
|
||||
missingUsers,
|
||||
modal,
|
||||
chat,
|
||||
}) => {
|
||||
const { sendInviteMessages, closeInviteViaLinkModal, openPremiumModal } = getActions();
|
||||
const { missingUsers } = modal || {};
|
||||
|
||||
const lang = useLang();
|
||||
const [selectedMemberIds, setSelectedMemberIds] = useState<string[]>([]);
|
||||
@ -196,8 +197,8 @@ const InviteViaLinkModal: FC<OwnProps & StateProps> = ({
|
||||
};
|
||||
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global, { chatId }): StateProps => {
|
||||
const chat = chatId ? selectChat(global, chatId) : undefined;
|
||||
(global, { modal }): StateProps => {
|
||||
const chat = modal?.chatId ? selectChat(global, modal.chatId) : undefined;
|
||||
|
||||
return {
|
||||
chat,
|
||||
|
||||
@ -8,8 +8,8 @@ import { Bundles } from '../../../util/moduleLoader';
|
||||
import useModuleLoader from '../../../hooks/useModuleLoader';
|
||||
|
||||
const MapModalAsync: FC<OwnProps> = (props) => {
|
||||
const { geoPoint } = props;
|
||||
const MapModal = useModuleLoader(Bundles.Extra, 'MapModal', !geoPoint);
|
||||
const { modal } = props;
|
||||
const MapModal = useModuleLoader(Bundles.Extra, 'MapModal', !modal);
|
||||
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
return MapModal ? <MapModal {...props} /> : undefined;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import React, { memo, useMemo } from '../../../lib/teact/teact';
|
||||
import { getActions } from '../../../global';
|
||||
|
||||
import type { ApiGeoPoint } from '../../../api/types';
|
||||
import type { TabState } from '../../../global/types';
|
||||
|
||||
import { prepareMapUrl } from '../../../util/map';
|
||||
import { IS_IOS, IS_MAC_OS } from '../../../util/windowEnvironment';
|
||||
@ -15,13 +15,14 @@ import Modal from '../../ui/Modal';
|
||||
import styles from './MapModal.module.scss';
|
||||
|
||||
export type OwnProps = {
|
||||
geoPoint?: ApiGeoPoint;
|
||||
zoom?: number;
|
||||
modal: TabState['mapModal'];
|
||||
};
|
||||
|
||||
const OpenMapModal = ({ geoPoint, zoom }: OwnProps) => {
|
||||
const OpenMapModal = ({ modal }: OwnProps) => {
|
||||
const { closeMapModal } = getActions();
|
||||
|
||||
const { point: geoPoint, zoom } = modal || {};
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
const isOpen = Boolean(geoPoint);
|
||||
|
||||
@ -8,8 +8,8 @@ import { Bundles } from '../../../util/moduleLoader';
|
||||
import useModuleLoader from '../../../hooks/useModuleLoader';
|
||||
|
||||
const OneTimeMediaModalAsync: FC<OwnProps> = (props) => {
|
||||
const { info } = props;
|
||||
const OneTimeMediaModal = useModuleLoader(Bundles.Extra, 'OneTimeMediaModal', !info);
|
||||
const { modal } = props;
|
||||
const OneTimeMediaModal = useModuleLoader(Bundles.Extra, 'OneTimeMediaModal', !modal);
|
||||
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
return OneTimeMediaModal ? <OneTimeMediaModal {...props} /> : undefined;
|
||||
|
||||
@ -20,23 +20,23 @@ import Button from '../../ui/Button';
|
||||
import styles from './OneTimeMediaModal.module.scss';
|
||||
|
||||
export type OwnProps = {
|
||||
info: TabState['oneTimeMediaModal'];
|
||||
modal: TabState['oneTimeMediaModal'];
|
||||
};
|
||||
|
||||
const OneTimeMediaModal = ({
|
||||
info,
|
||||
modal,
|
||||
}: OwnProps) => {
|
||||
const {
|
||||
closeOneTimeMediaModal,
|
||||
} = getActions();
|
||||
|
||||
const lang = useLang();
|
||||
const message = useCurrentOrPrev(info?.message, true);
|
||||
const message = useCurrentOrPrev(modal?.message, true);
|
||||
|
||||
const {
|
||||
shouldRender,
|
||||
transitionClassNames,
|
||||
} = useShowTransition(Boolean(info));
|
||||
} = useShowTransition(Boolean(modal));
|
||||
|
||||
const handlePlayVoice = useLastCallback(() => {
|
||||
return undefined;
|
||||
|
||||
@ -8,8 +8,8 @@ import { Bundles } from '../../../util/moduleLoader';
|
||||
import useModuleLoader from '../../../hooks/useModuleLoader';
|
||||
|
||||
const UrlAuthModalAsync: FC<OwnProps> = (props) => {
|
||||
const { urlAuth } = props;
|
||||
const UrlAuthModal = useModuleLoader(Bundles.Extra, 'UrlAuthModal', !urlAuth);
|
||||
const { modal } = props;
|
||||
const UrlAuthModal = useModuleLoader(Bundles.Extra, 'UrlAuthModal', !modal);
|
||||
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
return UrlAuthModal ? <UrlAuthModal {...props} /> : undefined;
|
||||
|
||||
@ -2,11 +2,13 @@ import type { FC } from '../../../lib/teact/teact';
|
||||
import React, {
|
||||
memo, useCallback, useEffect, useState,
|
||||
} from '../../../lib/teact/teact';
|
||||
import { getActions, getGlobal } from '../../../global';
|
||||
import { getActions, getGlobal, withGlobal } from '../../../global';
|
||||
|
||||
import type { ApiUser } from '../../../api/types';
|
||||
import type { TabState } from '../../../global/types';
|
||||
|
||||
import { getUserFullName } from '../../../global/helpers';
|
||||
import { selectUser } from '../../../global/selectors';
|
||||
import { ensureProtocol } from '../../../util/ensureProtocol';
|
||||
import renderText from '../../common/helpers/renderText';
|
||||
|
||||
@ -19,25 +21,28 @@ import ConfirmDialog from '../../ui/ConfirmDialog';
|
||||
import styles from './UrlAuthModal.module.scss';
|
||||
|
||||
export type OwnProps = {
|
||||
urlAuth?: TabState['urlAuth'];
|
||||
currentUserName?: string;
|
||||
modal?: TabState['urlAuth'];
|
||||
};
|
||||
|
||||
const UrlAuthModal: FC<OwnProps> = ({
|
||||
urlAuth, currentUserName,
|
||||
type StateProps = {
|
||||
currentUser?: ApiUser;
|
||||
};
|
||||
|
||||
const UrlAuthModal: FC<OwnProps & StateProps> = ({
|
||||
modal, currentUser,
|
||||
}) => {
|
||||
const { closeUrlAuthModal, acceptBotUrlAuth, acceptLinkUrlAuth } = getActions();
|
||||
const [isLoginChecked, setLoginChecked] = useState(true);
|
||||
const [isWriteAccessChecked, setWriteAccessChecked] = useState(true);
|
||||
const currentAuth = useCurrentOrPrev(urlAuth, false);
|
||||
const currentAuth = useCurrentOrPrev(modal, false);
|
||||
const { domain, botId, shouldRequestWriteAccess } = currentAuth?.request || {};
|
||||
const bot = botId ? getGlobal().users.byId[botId] : undefined;
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
const handleOpen = useCallback(() => {
|
||||
if (urlAuth?.url && isLoginChecked) {
|
||||
const acceptAction = urlAuth.button ? acceptBotUrlAuth : acceptLinkUrlAuth;
|
||||
if (modal?.url && isLoginChecked) {
|
||||
const acceptAction = modal.button ? acceptBotUrlAuth : acceptLinkUrlAuth;
|
||||
acceptAction({
|
||||
isWriteAllowed: isWriteAccessChecked,
|
||||
});
|
||||
@ -46,7 +51,7 @@ const UrlAuthModal: FC<OwnProps> = ({
|
||||
}
|
||||
closeUrlAuthModal();
|
||||
}, [
|
||||
urlAuth, isLoginChecked, closeUrlAuthModal, acceptBotUrlAuth, acceptLinkUrlAuth, isWriteAccessChecked, currentAuth,
|
||||
modal, isLoginChecked, closeUrlAuthModal, acceptBotUrlAuth, acceptLinkUrlAuth, isWriteAccessChecked, currentAuth,
|
||||
]);
|
||||
|
||||
const handleDismiss = useCallback(() => {
|
||||
@ -68,7 +73,7 @@ const UrlAuthModal: FC<OwnProps> = ({
|
||||
|
||||
return (
|
||||
<ConfirmDialog
|
||||
isOpen={Boolean(urlAuth?.url)}
|
||||
isOpen={Boolean(modal?.url)}
|
||||
onClose={handleDismiss}
|
||||
title={lang('OpenUrlTitle')}
|
||||
confirmLabel={lang('OpenUrlTitle')}
|
||||
@ -81,7 +86,7 @@ const UrlAuthModal: FC<OwnProps> = ({
|
||||
label={(
|
||||
<>
|
||||
{renderText(
|
||||
lang('Conversation.OpenBotLinkLogin', [domain, currentUserName]),
|
||||
lang('Conversation.OpenBotLinkLogin', [domain, getUserFullName(currentUser)]),
|
||||
['simple_markdown'],
|
||||
)}
|
||||
</>
|
||||
@ -109,5 +114,11 @@ const UrlAuthModal: FC<OwnProps> = ({
|
||||
</ConfirmDialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(UrlAuthModal);
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global): StateProps => {
|
||||
const currentUser = selectUser(global, global.currentUserId!);
|
||||
return {
|
||||
currentUser,
|
||||
};
|
||||
},
|
||||
)(UrlAuthModal));
|
||||
|
||||
@ -8,8 +8,8 @@ import { Bundles } from '../../../util/moduleLoader';
|
||||
import useModuleLoader from '../../../hooks/useModuleLoader';
|
||||
|
||||
const WebAppModalAsync: FC<OwnProps> = (props) => {
|
||||
const { webApp } = props;
|
||||
const WebAppModal = useModuleLoader(Bundles.Extra, 'WebAppModal', !webApp);
|
||||
const { modal } = props;
|
||||
const WebAppModal = useModuleLoader(Bundles.Extra, 'WebAppModal', !modal);
|
||||
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
return WebAppModal ? <WebAppModal {...props} /> : undefined;
|
||||
|
||||
@ -52,7 +52,7 @@ type WebAppButton = {
|
||||
};
|
||||
|
||||
export type OwnProps = {
|
||||
webApp?: TabState['webApp'];
|
||||
modal?: TabState['webApp'];
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
@ -88,7 +88,7 @@ const DEFAULT_BUTTON_TEXT: Record<string, string> = {
|
||||
};
|
||||
|
||||
const WebAppModal: FC<OwnProps & StateProps> = ({
|
||||
webApp,
|
||||
modal,
|
||||
chat,
|
||||
bot,
|
||||
attachBot,
|
||||
@ -141,7 +141,7 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
|
||||
const lang = useLang();
|
||||
const {
|
||||
url, buttonText, queryId, replyInfo,
|
||||
} = webApp || {};
|
||||
} = modal || {};
|
||||
const isOpen = Boolean(url);
|
||||
const isSimple = Boolean(buttonText);
|
||||
|
||||
@ -173,7 +173,7 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const handleRefreshClick = useLastCallback(() => {
|
||||
reloadFrame(webApp!.url);
|
||||
reloadFrame(modal!.url);
|
||||
});
|
||||
|
||||
const handleClose = useLastCallback(() => {
|
||||
@ -215,11 +215,11 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
|
||||
|
||||
useSyncEffect(([prevIsPaymentModalOpen]) => {
|
||||
if (isPaymentModalOpen === prevIsPaymentModalOpen) return;
|
||||
if (webApp?.slug && !isPaymentModalOpen && paymentStatus) {
|
||||
if (modal?.slug && !isPaymentModalOpen && paymentStatus) {
|
||||
sendEvent({
|
||||
eventType: 'invoice_closed',
|
||||
eventData: {
|
||||
slug: webApp.slug,
|
||||
slug: modal.slug,
|
||||
status: paymentStatus,
|
||||
},
|
||||
});
|
||||
@ -227,7 +227,7 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
|
||||
slug: undefined,
|
||||
});
|
||||
}
|
||||
}, [isPaymentModalOpen, paymentStatus, sendEvent, setWebAppPaymentSlug, webApp]);
|
||||
}, [isPaymentModalOpen, paymentStatus, sendEvent, modal?.slug]);
|
||||
|
||||
const handleRemoveAttachBot = useLastCallback(() => {
|
||||
toggleAttachBot({
|
||||
@ -693,8 +693,8 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
|
||||
};
|
||||
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global, { webApp }): StateProps => {
|
||||
const { botId } = webApp || {};
|
||||
(global, { modal }): StateProps => {
|
||||
const { botId } = modal || {};
|
||||
const attachBot = botId ? global.attachMenu.bots[botId] : undefined;
|
||||
const bot = botId ? selectUser(global, botId) : undefined;
|
||||
const chat = selectCurrentChat(global);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user