Support layer 201 (#5794)
This commit is contained in:
parent
10cfa5f22c
commit
92d9f0736c
@ -92,6 +92,9 @@ export interface GramJsAppConfig extends LimitsConfig {
|
||||
stars_paid_message_commission_permille?: number;
|
||||
stars_paid_message_amount_max?: number;
|
||||
stargifts_pinned_to_top_limit?: number;
|
||||
freeze_since_date?: number;
|
||||
freeze_until_date?: number;
|
||||
freeze_appeal_url?: string;
|
||||
}
|
||||
|
||||
function buildEmojiSounds(appConfig: GramJsAppConfig) {
|
||||
@ -185,5 +188,8 @@ export function buildAppConfig(json: GramJs.TypeJSONValue, hash: number): ApiApp
|
||||
starRefStartPrefixes: appConfig.starref_start_param_prefixes,
|
||||
tonExplorerUrl: appConfig.ton_blockchain_explorer_url,
|
||||
savedGiftPinLimit: appConfig.stargifts_pinned_to_top_limit,
|
||||
freezeSinceDate: appConfig.freeze_since_date,
|
||||
freezeUntilDate: appConfig.freeze_until_date,
|
||||
freezeAppealUrl: appConfig.freeze_appeal_url,
|
||||
};
|
||||
}
|
||||
|
||||
@ -413,6 +413,27 @@ export function buildApiMessageAction(action: GramJs.TypeMessageAction): ApiMess
|
||||
savedId: savedId && buildApiPeerId(savedId, 'user'),
|
||||
};
|
||||
}
|
||||
if (action instanceof GramJs.MessageActionPaidMessagesPrice) {
|
||||
const {
|
||||
stars,
|
||||
} = action;
|
||||
return {
|
||||
mediaType: 'action',
|
||||
type: 'paidMessagesPrice',
|
||||
stars: stars.toJSNumber(),
|
||||
};
|
||||
}
|
||||
if (action instanceof GramJs.MessageActionPaidMessagesRefunded) {
|
||||
const {
|
||||
stars, count,
|
||||
} = action;
|
||||
return {
|
||||
mediaType: 'action',
|
||||
type: 'paidMessagesRefunded',
|
||||
stars: stars.toJSNumber(),
|
||||
count,
|
||||
};
|
||||
}
|
||||
|
||||
return UNSUPPORTED_ACTION;
|
||||
}
|
||||
|
||||
@ -307,6 +307,12 @@ export async function invokeRequest<T extends GramJs.AnyRequest>(
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
const message = err instanceof RPCError ? err.errorMessage : err.message;
|
||||
|
||||
if (message.includes('FROZEN_METHOD_INVALID')) {
|
||||
dispatchNotSupportedInFrozenAccountUpdate(err, request);
|
||||
}
|
||||
|
||||
if (shouldThrow) {
|
||||
throw err;
|
||||
}
|
||||
@ -441,6 +447,27 @@ export function dispatchErrorUpdate<T extends GramJs.AnyRequest>(err: Error, req
|
||||
});
|
||||
}
|
||||
|
||||
function dispatchNotSupportedInFrozenAccountUpdate<T extends GramJs.AnyRequest>(err: Error, request: T) {
|
||||
if (!(err instanceof RPCError)) return;
|
||||
const message = err.errorMessage;
|
||||
|
||||
if (
|
||||
request instanceof GramJs.messages.GetPinnedDialogs
|
||||
|| request instanceof GramJs.phone.GetGroupParticipants
|
||||
|| request instanceof GramJs.channels.GetParticipant
|
||||
|| request instanceof GramJs.channels.GetParticipants
|
||||
|| request instanceof GramJs.channels.GetForumTopics) {
|
||||
return;
|
||||
}
|
||||
|
||||
sendApiUpdate({
|
||||
'@type': 'notSupportedInFrozenAccount',
|
||||
error: {
|
||||
message,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function handleTerminatedSession() {
|
||||
try {
|
||||
await invokeRequest(new GramJs.users.GetFullUser({
|
||||
|
||||
@ -1775,20 +1775,17 @@ export async function fetchSponsoredMessages({ peer }: { peer: ApiPeer }) {
|
||||
};
|
||||
}
|
||||
|
||||
export async function viewSponsoredMessage({ peer, random }: { peer: ApiPeer; random: string }) {
|
||||
export async function viewSponsoredMessage({ random }: { random: string }) {
|
||||
await invokeRequest(new GramJs.messages.ViewSponsoredMessage({
|
||||
peer: buildInputPeer(peer.id, peer.accessHash),
|
||||
randomId: deserializeBytes(random),
|
||||
}));
|
||||
}
|
||||
|
||||
export function clickSponsoredMessage({
|
||||
peer,
|
||||
random,
|
||||
isMedia,
|
||||
isFullscreen,
|
||||
}: {
|
||||
peer: ApiPeer;
|
||||
random: string;
|
||||
isMedia?: boolean;
|
||||
isFullscreen?: boolean;
|
||||
@ -1796,23 +1793,19 @@ export function clickSponsoredMessage({
|
||||
return invokeRequest(new GramJs.messages.ClickSponsoredMessage({
|
||||
media: isMedia || undefined,
|
||||
fullscreen: isFullscreen || undefined,
|
||||
peer: buildInputPeer(peer.id, peer.accessHash),
|
||||
randomId: deserializeBytes(random),
|
||||
}));
|
||||
}
|
||||
|
||||
export async function reportSponsoredMessage({
|
||||
peer,
|
||||
randomId,
|
||||
option,
|
||||
}: {
|
||||
peer: ApiPeer;
|
||||
randomId: string;
|
||||
option: string;
|
||||
}) {
|
||||
try {
|
||||
const result = await invokeRequest(new GramJs.messages.ReportSponsoredMessage({
|
||||
peer: buildInputPeer(peer.id, peer.accessHash),
|
||||
randomId: deserializeBytes(randomId),
|
||||
option: deserializeBytes(option),
|
||||
}), {
|
||||
|
||||
@ -268,6 +268,17 @@ export interface ApiMessageActionExpiredContent extends ActionMediaType {
|
||||
isRoundVideo?: true;
|
||||
}
|
||||
|
||||
export interface ApiMessageActionPaidMessagesRefunded extends ActionMediaType {
|
||||
type: 'paidMessagesRefunded';
|
||||
count:number;
|
||||
stars:number;
|
||||
}
|
||||
|
||||
export interface ApiMessageActionPaidMessagesPrice extends ActionMediaType {
|
||||
type: 'paidMessagesPrice';
|
||||
stars:number;
|
||||
}
|
||||
|
||||
export interface ApiMessageActionUnsupported extends ActionMediaType {
|
||||
type: 'unsupported';
|
||||
}
|
||||
@ -284,4 +295,5 @@ export type ApiMessageAction = ApiMessageActionUnsupported | ApiMessageActionCha
|
||||
| ApiMessageActionTopicCreate | ApiMessageActionTopicEdit | ApiMessageActionSuggestProfilePhoto
|
||||
| ApiMessageActionChannelJoined | ApiMessageActionGiftCode | ApiMessageActionGiveawayLaunch
|
||||
| ApiMessageActionGiveawayResults | ApiMessageActionPaymentRefunded | ApiMessageActionGiftStars
|
||||
| ApiMessageActionPrizeStars | ApiMessageActionStarGift | ApiMessageActionStarGiftUnique;
|
||||
| ApiMessageActionPrizeStars | ApiMessageActionStarGift | ApiMessageActionStarGiftUnique
|
||||
| ApiMessageActionPaidMessagesRefunded | ApiMessageActionPaidMessagesPrice;
|
||||
|
||||
@ -243,6 +243,9 @@ export interface ApiAppConfig {
|
||||
starRefStartPrefixes?: string[];
|
||||
tonExplorerUrl?: string;
|
||||
savedGiftPinLimit?: number;
|
||||
freezeSinceDate?: number;
|
||||
freezeUntilDate?: number;
|
||||
freezeAppealUrl?: string;
|
||||
}
|
||||
|
||||
export interface ApiConfig {
|
||||
|
||||
@ -463,6 +463,11 @@ export type ApiUpdateError = {
|
||||
error: ApiError;
|
||||
};
|
||||
|
||||
export type ApiUpdateNotSupportedInFrozenAccountError = {
|
||||
'@type': 'notSupportedInFrozenAccount';
|
||||
error: ApiError;
|
||||
};
|
||||
|
||||
export type ApiUpdateConfig = {
|
||||
'@type': 'updateConfig';
|
||||
};
|
||||
@ -855,7 +860,7 @@ export type ApiUpdate = (
|
||||
ApiUpdateDeleteSavedHistory | ApiUpdatePremiumFloodWait | ApiUpdateStarsBalance |
|
||||
ApiUpdateQuickReplyMessage | ApiUpdateQuickReplies | ApiDeleteQuickReply | ApiUpdateDeleteQuickReplyMessages |
|
||||
ApiUpdateDeleteProfilePhoto | ApiUpdateNewProfilePhoto | ApiUpdateEntities | ApiUpdatePaidReactionPrivacy |
|
||||
ApiUpdateLangPackTooLong | ApiUpdateLangPack
|
||||
ApiUpdateLangPackTooLong | ApiUpdateLangPack | ApiUpdateNotSupportedInFrozenAccountError
|
||||
);
|
||||
|
||||
export type OnApiUpdate = (update: ApiUpdate) => void;
|
||||
|
||||
1
src/assets/font-icons/frozen-time.svg
Normal file
1
src/assets/font-icons/frozen-time.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="none"><path fill="#000" d="M19.58 16C23.868 14.353 27 10.153 27 5.294A3.306 3.306 0 0 0 23.703 2H7.297A3.305 3.305 0 0 0 4 5.294C4 10.153 7.05 14.353 11.42 16 7.132 17.647 4 21.847 4 26.706A3.306 3.306 0 0 0 7.297 30h16.406A3.306 3.306 0 0 0 27 26.706c0-4.859-3.133-9.059-7.42-10.706M5.65 5.294c0-.906.742-1.647 1.648-1.647h16.406c.906 0 1.648.741 1.648 1.647 0 5.435-4.451 9.8-9.81 9.8-5.358 0-9.892-4.365-9.892-9.8m18.054 23.059H7.297a1.653 1.653 0 0 1-1.648-1.647c0-5.435 4.451-9.8 9.81-9.8 5.358 0 9.892 4.365 9.892 9.8 0 .906-.742 1.647-1.648 1.647"/><path fill="#000" d="m9.688 24.235.824 1.4 4.947-3.13 5.029 3.13.824-1.4-5.853-3.623zM19.498 9l.99.741.989-1.317-.99-.742c-1.154-.906-2.802-.906-4.039 0-.577.494-1.401.494-2.06 0a3.47 3.47 0 0 0-4.123 0l-.824.742.99 1.317.906-.741a1.62 1.62 0 0 1 2.06 0c1.155.906 2.886.906 4.04 0 .66-.412 1.484-.412 2.061 0"/></svg>
|
||||
|
After Width: | Height: | Size: 942 B |
@ -1902,6 +1902,25 @@
|
||||
"PaidMessageTransaction_other" = "Fee for {count} Messages";
|
||||
"PaidMessageTransactionDescription" = "You receive **{percent}** of the price that you charge for each incoming message.";
|
||||
"PaidMessageTransactionTotal" = "Total";
|
||||
"TitleFrozenAccount" = "Your account is frozen!";
|
||||
"SubtitleFrozenAccount" = "Tap to view details and submit an appeal.";
|
||||
"ComposerTitleFrozenAccount" = "Your account is frozen";
|
||||
"ComposerSubtitleFrozenAccount" = "Tap to view details";
|
||||
"DescriptionRestrictedMedia" = "Posting media content is not allowed in this group.";
|
||||
"DescriptionScheduledPaidMediaNotAllowed" = "Posting scheduled paid media content is not allowed";
|
||||
"DescriptionScheduledPaidMessagesNotAllowed" = "Scheduled paid messages is not allowed";
|
||||
"FrozenAccountModalTitle" = "Your Account is Frozen";
|
||||
"FrozenAccountViolationTitle" = "Violation of Terms";
|
||||
"FrozenAccountViolationSubtitle" = "Your account was frozen for breaking Telegram's Terms and Conditions";
|
||||
"FrozenAccountReadOnlyTitle" = "Read-Only Mode";
|
||||
"FrozenAccountReadOnlySubtitle" = "You can access your account but can't send messages or take actions.";
|
||||
"FrozenAccountAppealTitle" = "Appeal Before Deactivation";
|
||||
"FrozenAccountAppealSubtitle" = "Appeal via {botLink} before {date} or your account will be deleted.";
|
||||
"ButtonAppeal" = "Submit an Appeal";
|
||||
"ButtonUnderstood" = "Understood";
|
||||
"ActionPaidMessageGroupPrice" = "Messages now cost **{stars}** in this group";
|
||||
"ActionPaidMessageGroupPriceFree" = "Messages are now free in this group";
|
||||
"ApiMessageActionPaidMessagesRefundedOutgoing" = "You refunded **{stars}** to {user}";
|
||||
"ApiMessageActionPaidMessagesRefundedIncoming" = "{user} refunded **{stars}** to you";
|
||||
"NotificationTitleNotSupportedInFrozenAccount" = "Your account is frozen";
|
||||
"NotificationMessageNotSupportedInFrozenAccount" = "This action is not available";
|
||||
BIN
src/assets/tgs/BannedDuck.tgs
Normal file
BIN
src/assets/tgs/BannedDuck.tgs
Normal file
Binary file not shown.
@ -97,3 +97,4 @@ export { default as ReceiptModal } from '../components/payment/ReceiptModal';
|
||||
export { default as InviteViaLinkModal } from '../components/modals/inviteViaLink/InviteViaLinkModal';
|
||||
export { default as OneTimeMediaModal } from '../components/modals/oneTimeMedia/OneTimeMediaModal';
|
||||
export { default as WebAppsCloseConfirmationModal } from '../components/main/WebAppsCloseConfirmationModal';
|
||||
export { default as FrozenAccountModal } from '../components/modals/frozenAccount/FrozenAccountModal';
|
||||
|
||||
@ -82,6 +82,7 @@ import {
|
||||
selectEditingMessage,
|
||||
selectEditingScheduledDraft,
|
||||
selectIsChatWithSelf,
|
||||
selectIsCurrentUserFrozen,
|
||||
selectIsCurrentUserPremium,
|
||||
selectIsInSelectMode,
|
||||
selectIsPremiumPurchaseBlocked,
|
||||
@ -291,6 +292,8 @@ type StateProps =
|
||||
isPaymentMessageConfirmDialogOpen: boolean;
|
||||
starsBalance: number;
|
||||
isStarsBalanceModalOpen: boolean;
|
||||
isAccountFrozen?: boolean;
|
||||
isAppConfigLoaded?: boolean;
|
||||
};
|
||||
|
||||
enum MainButtonState {
|
||||
@ -411,6 +414,8 @@ const Composer: FC<OwnProps & StateProps> = ({
|
||||
isPaymentMessageConfirmDialogOpen,
|
||||
starsBalance,
|
||||
isStarsBalanceModalOpen,
|
||||
isAccountFrozen,
|
||||
isAppConfigLoaded,
|
||||
}) => {
|
||||
const {
|
||||
sendMessage,
|
||||
@ -499,10 +504,10 @@ const Composer: FC<OwnProps & StateProps> = ({
|
||||
}, [chatId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (chatId && isReady && !isInStoryViewer) {
|
||||
if (isAppConfigLoaded && chatId && isReady && !isInStoryViewer) {
|
||||
loadScheduledHistory({ chatId });
|
||||
}
|
||||
}, [isReady, chatId, threadId, isInStoryViewer]);
|
||||
}, [isReady, chatId, threadId, isInStoryViewer, isAppConfigLoaded]);
|
||||
|
||||
useEffect(() => {
|
||||
const isChannelWithProfiles = isChannel && chat?.areProfilesShown;
|
||||
@ -1960,7 +1965,7 @@ const Composer: FC<OwnProps & StateProps> = ({
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{((!isComposerBlocked || canSendGifs || canSendStickers) && !isNeedPremium) && (
|
||||
{((!isComposerBlocked || canSendGifs || canSendStickers) && !isNeedPremium && !isAccountFrozen) && (
|
||||
<SymbolMenuButton
|
||||
chatId={chatId}
|
||||
threadId={threadId}
|
||||
@ -2373,6 +2378,8 @@ export default memo(withGlobal<OwnProps>(
|
||||
const isForwarding = chatId === tabState.forwardMessages.toChatId;
|
||||
const starsBalance = global.stars?.balance.amount || 0;
|
||||
const isStarsBalanceModalOpen = Boolean(tabState.starsBalanceModal);
|
||||
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
||||
const isAppConfigLoaded = global.isAppConfigLoaded;
|
||||
|
||||
return {
|
||||
availableReactions: global.reactions.availableReactions,
|
||||
@ -2457,6 +2464,8 @@ export default memo(withGlobal<OwnProps>(
|
||||
isPaymentMessageConfirmDialogOpen: tabState.isPaymentMessageConfirmDialogOpen,
|
||||
starsBalance,
|
||||
isStarsBalanceModalOpen,
|
||||
isAccountFrozen,
|
||||
isAppConfigLoaded,
|
||||
};
|
||||
},
|
||||
)(Composer));
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import QrPlane from '../../../assets/tgs/auth/QrPlane.tgs';
|
||||
import BannedDuck from '../../../assets/tgs/BannedDuck.tgs';
|
||||
import CameraFlip from '../../../assets/tgs/calls/CameraFlip.tgs';
|
||||
import HandFilled from '../../../assets/tgs/calls/HandFilled.tgs';
|
||||
import HandOutline from '../../../assets/tgs/calls/HandOutline.tgs';
|
||||
@ -66,4 +67,5 @@ export const LOCAL_TGS_URLS = {
|
||||
StarReaction,
|
||||
Report,
|
||||
SearchingDuck,
|
||||
BannedDuck,
|
||||
};
|
||||
|
||||
@ -9,7 +9,9 @@ import type { FoldersActions } from '../../hooks/reducers/useFoldersReducer';
|
||||
import type { ReducerAction } from '../../hooks/useReducer';
|
||||
import { LeftColumnContent, SettingsScreens } from '../../types';
|
||||
|
||||
import { selectCurrentChat, selectIsForumPanelOpen, selectTabState } from '../../global/selectors';
|
||||
import {
|
||||
selectCurrentChat, selectIsCurrentUserFrozen, selectIsForumPanelOpen, selectTabState,
|
||||
} from '../../global/selectors';
|
||||
import {
|
||||
IS_APP, IS_FIREFOX, IS_MAC_OS, IS_TOUCH_ENV, LAYERS_ANIMATION_NAME,
|
||||
} from '../../util/browser/windowEnvironment';
|
||||
@ -52,6 +54,7 @@ type StateProps = {
|
||||
isClosingSearch?: boolean;
|
||||
archiveSettings: GlobalState['archiveSettings'];
|
||||
isArchivedStoryRibbonShown?: boolean;
|
||||
isAccountFrozen?: boolean;
|
||||
};
|
||||
|
||||
enum ContentType {
|
||||
@ -86,6 +89,7 @@ function LeftColumn({
|
||||
isClosingSearch,
|
||||
archiveSettings,
|
||||
isArchivedStoryRibbonShown,
|
||||
isAccountFrozen,
|
||||
}: OwnProps & StateProps) {
|
||||
const {
|
||||
setGlobalSearchQuery,
|
||||
@ -545,6 +549,7 @@ function LeftColumn({
|
||||
isElectronUpdateAvailable={isElectronUpdateAvailable}
|
||||
isForumPanelOpen={isForumPanelOpen}
|
||||
onTopicSearch={handleTopicSearch}
|
||||
isAccountFrozen={isAccountFrozen}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -598,6 +603,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
const isChatOpen = Boolean(currentChat?.id);
|
||||
const isForumPanelOpen = selectIsForumPanelOpen(global);
|
||||
const forumPanelChatId = tabState.forumPanelChatId;
|
||||
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
||||
|
||||
return {
|
||||
searchQuery: query,
|
||||
@ -616,6 +622,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
isClosingSearch: tabState.globalSearch.isClosing,
|
||||
archiveSettings,
|
||||
isArchivedStoryRibbonShown: isArchivedRibbonShown,
|
||||
isAccountFrozen,
|
||||
};
|
||||
},
|
||||
)(LeftColumn));
|
||||
|
||||
@ -2,6 +2,7 @@ import type { FC } from '../../lib/teact/teact';
|
||||
import React, {
|
||||
useCallback, useEffect, useMemo, useState,
|
||||
} from '../../lib/teact/teact';
|
||||
import { getActions } from '../../global';
|
||||
|
||||
import buildClassName from '../../util/buildClassName';
|
||||
|
||||
@ -19,6 +20,7 @@ type OwnProps = {
|
||||
onNewPrivateChat: () => void;
|
||||
onNewChannel: () => void;
|
||||
onNewGroup: () => void;
|
||||
isAccountFrozen?: boolean;
|
||||
};
|
||||
|
||||
const NewChatButton: FC<OwnProps> = ({
|
||||
@ -26,8 +28,10 @@ const NewChatButton: FC<OwnProps> = ({
|
||||
onNewPrivateChat,
|
||||
onNewChannel,
|
||||
onNewGroup,
|
||||
isAccountFrozen,
|
||||
}) => {
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||
const { openFrozenAccountModal } = getActions();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isShown) {
|
||||
@ -44,8 +48,12 @@ const NewChatButton: FC<OwnProps> = ({
|
||||
);
|
||||
|
||||
const toggleIsMenuOpen = useCallback(() => {
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
return;
|
||||
}
|
||||
setIsMenuOpen(!isMenuOpen);
|
||||
}, [isMenuOpen]);
|
||||
}, [isMenuOpen, isAccountFrozen]);
|
||||
|
||||
const handleClose = useCallback(() => {
|
||||
setIsMenuOpen(false);
|
||||
|
||||
@ -33,6 +33,7 @@ import {
|
||||
selectChatMessage,
|
||||
selectCurrentMessageList,
|
||||
selectDraft,
|
||||
selectIsCurrentUserFrozen,
|
||||
selectIsForumPanelClosed,
|
||||
selectIsForumPanelOpen,
|
||||
selectNotifyDefaults,
|
||||
@ -114,6 +115,7 @@ type StateProps = {
|
||||
lastMessage?: ApiMessage;
|
||||
currentUserId: string;
|
||||
isSynced?: boolean;
|
||||
isAccountFrozen?: boolean;
|
||||
};
|
||||
|
||||
const Chat: FC<OwnProps & StateProps> = ({
|
||||
@ -151,6 +153,7 @@ const Chat: FC<OwnProps & StateProps> = ({
|
||||
className,
|
||||
isSynced,
|
||||
onDragEnter,
|
||||
isAccountFrozen,
|
||||
}) => {
|
||||
const {
|
||||
openChat,
|
||||
@ -163,6 +166,7 @@ const Chat: FC<OwnProps & StateProps> = ({
|
||||
closeForumPanel,
|
||||
setShouldCloseRightColumn,
|
||||
reportMessages,
|
||||
openFrozenAccountModal,
|
||||
} = getActions();
|
||||
|
||||
const { isMobile } = useAppLayout();
|
||||
@ -248,11 +252,21 @@ const Chat: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const handleDelete = useLastCallback(() => {
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
return;
|
||||
}
|
||||
|
||||
markRenderDeleteModal();
|
||||
openDeleteModal();
|
||||
});
|
||||
|
||||
const handleMute = useLastCallback(() => {
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
return;
|
||||
}
|
||||
|
||||
markRenderMuteModal();
|
||||
openMuteModal();
|
||||
});
|
||||
@ -263,6 +277,11 @@ const Chat: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const handleReport = useLastCallback(() => {
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!chat) return;
|
||||
reportMessages({ chatId: chat.id, messageIds: [] });
|
||||
});
|
||||
@ -468,6 +487,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
|
||||
const storyData = lastMessage?.content.storyData;
|
||||
const lastMessageStory = storyData && selectPeerStory(global, storyData.peerId, storyData.id);
|
||||
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
||||
|
||||
return {
|
||||
chat,
|
||||
@ -494,6 +514,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
topics: topicsInfo?.topicsById,
|
||||
isSynced: global.isSynced,
|
||||
lastMessageStory,
|
||||
isAccountFrozen,
|
||||
};
|
||||
},
|
||||
)(Chat));
|
||||
|
||||
@ -13,7 +13,7 @@ import type { TabWithProperties } from '../../ui/TabList';
|
||||
import { SettingsScreens } from '../../../types';
|
||||
|
||||
import { ALL_FOLDER_ID } from '../../../config';
|
||||
import { selectCanShareFolder, selectTabState } from '../../../global/selectors';
|
||||
import { selectCanShareFolder, selectIsCurrentUserFrozen, selectTabState } from '../../../global/selectors';
|
||||
import { selectCurrentLimit } from '../../../global/selectors/limits';
|
||||
import { IS_TOUCH_ENV } from '../../../util/browser/windowEnvironment';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
@ -60,6 +60,7 @@ type StateProps = {
|
||||
archiveSettings: GlobalState['archiveSettings'];
|
||||
isStoryRibbonShown?: boolean;
|
||||
sessions?: Record<string, ApiSession>;
|
||||
isAccountFrozen?: boolean;
|
||||
};
|
||||
|
||||
const SAVED_MESSAGES_HOTKEY = '0';
|
||||
@ -85,6 +86,7 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
|
||||
archiveSettings,
|
||||
isStoryRibbonShown,
|
||||
sessions,
|
||||
isAccountFrozen,
|
||||
}) => {
|
||||
const {
|
||||
loadChatFolders,
|
||||
@ -368,6 +370,7 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
|
||||
canDisplayArchive={(hasArchivedChats || hasArchivedStories) && !archiveSettings.isHidden}
|
||||
archiveSettings={archiveSettings}
|
||||
sessions={sessions}
|
||||
isAccountFrozen={isAccountFrozen}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -432,6 +435,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
} = global;
|
||||
const { shouldSkipHistoryAnimations, activeChatFolder } = selectTabState(global);
|
||||
const { storyViewer: { isRibbonShown: isStoryRibbonShown } } = selectTabState(global);
|
||||
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
||||
|
||||
return {
|
||||
chatFoldersById,
|
||||
@ -448,6 +452,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
archiveSettings,
|
||||
isStoryRibbonShown,
|
||||
sessions,
|
||||
isAccountFrozen,
|
||||
};
|
||||
},
|
||||
)(ChatFolders));
|
||||
|
||||
@ -39,6 +39,7 @@ import Loading from '../../ui/Loading';
|
||||
import Archive from './Archive';
|
||||
import Chat from './Chat';
|
||||
import EmptyFolder from './EmptyFolder';
|
||||
import FrozenAccountNotification from './FrozenAccountNotification';
|
||||
import UnconfirmedSession from './UnconfirmedSession';
|
||||
|
||||
type OwnProps = {
|
||||
@ -53,6 +54,7 @@ type OwnProps = {
|
||||
foldersDispatch?: FolderEditDispatch;
|
||||
onSettingsScreenSelect?: (screen: SettingsScreens) => void;
|
||||
onLeftColumnContentChange?: (content: LeftColumnContent) => void;
|
||||
isAccountFrozen?: boolean;
|
||||
};
|
||||
|
||||
const INTERSECTION_THROTTLE = 200;
|
||||
@ -71,12 +73,14 @@ const ChatList: FC<OwnProps> = ({
|
||||
foldersDispatch,
|
||||
onSettingsScreenSelect,
|
||||
onLeftColumnContentChange,
|
||||
isAccountFrozen,
|
||||
}) => {
|
||||
const {
|
||||
openChat,
|
||||
openNextChat,
|
||||
closeForumPanel,
|
||||
toggleStoryRibbon,
|
||||
openFrozenAccountModal,
|
||||
} = getActions();
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
@ -91,6 +95,7 @@ const ChatList: FC<OwnProps> = ({
|
||||
);
|
||||
|
||||
const shouldDisplayArchive = isAllFolder && canDisplayArchive && archiveSettings;
|
||||
const shouldShowFrozenAccountNotification = isAccountFrozen && isAllFolder;
|
||||
|
||||
const orderedIds = useFolderManagerForOrderedIds(resolvedFolderId);
|
||||
usePeerStoriesPolling(orderedIds);
|
||||
@ -98,6 +103,7 @@ const ChatList: FC<OwnProps> = ({
|
||||
const chatsHeight = (orderedIds?.length || 0) * CHAT_HEIGHT_PX;
|
||||
const archiveHeight = shouldDisplayArchive
|
||||
? archiveSettings?.isMinimized ? ARCHIVE_MINIMIZED_HEIGHT : CHAT_HEIGHT_PX : 0;
|
||||
const frozenNotificationHeight = shouldShowFrozenAccountNotification ? 68 : 0;
|
||||
|
||||
const { orderDiffById, getAnimationType } = useOrderDiff(orderedIds);
|
||||
|
||||
@ -108,8 +114,8 @@ const ChatList: FC<OwnProps> = ({
|
||||
const current = sessionsArray.find((session) => session.isCurrent);
|
||||
if (!current || getServerTime() - current.dateCreated < FRESH_AUTH_PERIOD) return false;
|
||||
|
||||
return isAllFolder && sessionsArray.some((session) => session.isUnconfirmed);
|
||||
}, [isAllFolder, sessions]);
|
||||
return !isAccountFrozen && isAllFolder && sessionsArray.some((session) => session.isUnconfirmed);
|
||||
}, [isAllFolder, sessions, isAccountFrozen]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!shouldShowUnconfirmedSessions) setUnconfirmedSessionHeight(0);
|
||||
@ -174,6 +180,10 @@ const ChatList: FC<OwnProps> = ({
|
||||
closeForumPanel();
|
||||
});
|
||||
|
||||
const handleFrozenAccountNotificationClick = useLastCallback(() => {
|
||||
openFrozenAccountModal();
|
||||
});
|
||||
|
||||
const handleArchivedDragEnter = useLastCallback(() => {
|
||||
if (shouldIgnoreDragRef.current) {
|
||||
shouldIgnoreDragRef.current = false;
|
||||
@ -215,7 +225,8 @@ const ChatList: FC<OwnProps> = ({
|
||||
|
||||
return viewportIds!.map((id, i) => {
|
||||
const isPinned = viewportOffset + i < pinnedCount;
|
||||
const offsetTop = unconfirmedSessionHeight + archiveHeight + (viewportOffset + i) * CHAT_HEIGHT_PX;
|
||||
const offsetTop = unconfirmedSessionHeight + archiveHeight + frozenNotificationHeight
|
||||
+ (viewportOffset + i) * CHAT_HEIGHT_PX;
|
||||
|
||||
return (
|
||||
<Chat
|
||||
@ -244,7 +255,7 @@ const ChatList: FC<OwnProps> = ({
|
||||
preloadBackwards={CHAT_LIST_SLICE}
|
||||
withAbsolutePositioning
|
||||
beforeChildren={renderedOverflowTrigger}
|
||||
maxHeight={chatsHeight + archiveHeight + unconfirmedSessionHeight}
|
||||
maxHeight={chatsHeight + archiveHeight + frozenNotificationHeight + unconfirmedSessionHeight}
|
||||
onLoadMore={getMore}
|
||||
onDragLeave={handleDragLeave}
|
||||
>
|
||||
@ -255,6 +266,12 @@ const ChatList: FC<OwnProps> = ({
|
||||
onHeightChange={setUnconfirmedSessionHeight}
|
||||
/>
|
||||
)}
|
||||
{shouldShowFrozenAccountNotification && (
|
||||
<FrozenAccountNotification
|
||||
key="frozen"
|
||||
onClick={handleFrozenAccountNotificationClick}
|
||||
/>
|
||||
)}
|
||||
{shouldDisplayArchive && (
|
||||
<Archive
|
||||
key="archive"
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
.root {
|
||||
background-color: var(--color-background-secondary);
|
||||
margin-inline: -0.5rem;
|
||||
padding-block: 0.75rem;
|
||||
padding-inline: 1rem;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.85;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
color: var(--color-error);
|
||||
font-weight: var(--font-weight-medium);
|
||||
font-size: 1rem;
|
||||
line-height: 1rem;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 0.875rem;
|
||||
margin-top: 0.25rem;
|
||||
line-height: 1rem;
|
||||
}
|
||||
25
src/components/left/main/FrozenAccountNotification.tsx
Normal file
25
src/components/left/main/FrozenAccountNotification.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import React, { memo } from '../../../lib/teact/teact';
|
||||
|
||||
import useLang from '../../../hooks/useLang';
|
||||
|
||||
import styles from './FrozenAccountNotification.module.scss';
|
||||
|
||||
type OwnProps = {
|
||||
onClick: () => void;
|
||||
};
|
||||
|
||||
const FrozenAccountNotification = ({ onClick }: OwnProps) => {
|
||||
const lang = useLang();
|
||||
|
||||
return (
|
||||
<div
|
||||
className={styles.root}
|
||||
onClick={onClick}
|
||||
>
|
||||
<div className={styles.title}>{lang('TitleFrozenAccount')}</div>
|
||||
<div className={styles.subtitle}>{lang('SubtitleFrozenAccount')}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(FrozenAccountNotification);
|
||||
@ -43,6 +43,7 @@ type OwnProps = {
|
||||
onContentChange: (content: LeftColumnContent) => void;
|
||||
onSettingsScreenSelect: (screen: SettingsScreens) => void;
|
||||
onTopicSearch: NoneToVoidFunction;
|
||||
isAccountFrozen?: boolean;
|
||||
onReset: () => void;
|
||||
};
|
||||
|
||||
@ -67,6 +68,7 @@ const LeftMain: FC<OwnProps> = ({
|
||||
onSettingsScreenSelect,
|
||||
onReset,
|
||||
onTopicSearch,
|
||||
isAccountFrozen,
|
||||
}) => {
|
||||
const { closeForumPanel } = getActions();
|
||||
const [isNewChatButtonShown, setIsNewChatButtonShown] = useState(IS_TOUCH_ENV);
|
||||
@ -243,6 +245,7 @@ const LeftMain: FC<OwnProps> = ({
|
||||
onNewPrivateChat={handleSelectContacts}
|
||||
onNewChannel={handleSelectNewChannel}
|
||||
onNewGroup={handleSelectNewGroup}
|
||||
isAccountFrozen={isAccountFrozen}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -5,7 +5,7 @@ import { getActions, withGlobal } from '../../../global';
|
||||
import type { ApiEmojiStatusCollectible, ApiEmojiStatusType, ApiSticker } from '../../../api/types';
|
||||
|
||||
import { EMOJI_STATUS_LOOP_LIMIT } from '../../../config';
|
||||
import { selectUser } from '../../../global/selectors';
|
||||
import { selectIsCurrentUserFrozen, selectUser } from '../../../global/selectors';
|
||||
import { getServerTime } from '../../../util/serverTime';
|
||||
|
||||
import useTimeout from '../../../hooks/schedulers/useTimeout';
|
||||
@ -22,13 +22,14 @@ import StatusPickerMenu from './StatusPickerMenu.async';
|
||||
interface StateProps {
|
||||
emojiStatus?: ApiEmojiStatusType;
|
||||
collectibleStatuses?: ApiEmojiStatusType[];
|
||||
isAccountFrozen?: boolean;
|
||||
}
|
||||
|
||||
const EFFECT_DURATION_MS = 1500;
|
||||
const EMOJI_STATUS_SIZE = 24;
|
||||
|
||||
const StatusButton: FC<StateProps> = ({ emojiStatus, collectibleStatuses }) => {
|
||||
const { setEmojiStatus, loadCurrentUser } = getActions();
|
||||
const StatusButton: FC<StateProps> = ({ emojiStatus, collectibleStatuses, isAccountFrozen }) => {
|
||||
const { setEmojiStatus, loadCurrentUser, openFrozenAccountModal } = getActions();
|
||||
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
const buttonRef = useRef<HTMLButtonElement>(null);
|
||||
@ -60,8 +61,12 @@ const StatusButton: FC<StateProps> = ({ emojiStatus, collectibleStatuses }) => {
|
||||
useTimeout(hideEffect, isEffectShown ? EFFECT_DURATION_MS : undefined);
|
||||
|
||||
const handleEmojiStatusClick = useCallback(() => {
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
return;
|
||||
}
|
||||
openStatusPicker();
|
||||
}, [openStatusPicker]);
|
||||
}, [openStatusPicker, isAccountFrozen]);
|
||||
|
||||
return (
|
||||
<div className="StatusButton extra-spacing">
|
||||
@ -105,9 +110,11 @@ export default memo(withGlobal((global): StateProps => {
|
||||
const { currentUserId } = global;
|
||||
const currentUser = currentUserId ? selectUser(global, currentUserId) : undefined;
|
||||
const collectibleStatuses = global.collectibleEmojiStatuses?.statuses;
|
||||
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
||||
|
||||
return {
|
||||
emojiStatus: currentUser?.emojiStatus,
|
||||
collectibleStatuses,
|
||||
isAccountFrozen,
|
||||
};
|
||||
})(StatusButton));
|
||||
|
||||
@ -6,7 +6,10 @@ import type { ApiPrivacySettings } from '../../../api/types';
|
||||
import type { GlobalState } from '../../../global/types';
|
||||
import { SettingsScreens } from '../../../types';
|
||||
|
||||
import { selectCanSetPasscode, selectIsCurrentUserPremium } from '../../../global/selectors';
|
||||
import {
|
||||
selectCanSetPasscode, selectIsCurrentUserFrozen,
|
||||
selectIsCurrentUserPremium,
|
||||
} from '../../../global/selectors';
|
||||
import { selectSharedSettings } from '../../../global/selectors/sharedState';
|
||||
|
||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||
@ -37,6 +40,7 @@ type StateProps = {
|
||||
shouldNewNonContactPeersRequirePremium?: boolean;
|
||||
shouldChargeForMessages: boolean;
|
||||
canDisplayChatInTitle?: boolean;
|
||||
isCurrentUserFrozen?: boolean;
|
||||
privacy: GlobalState['settings']['privacy'];
|
||||
};
|
||||
|
||||
@ -58,6 +62,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
||||
privacy,
|
||||
onScreenSelect,
|
||||
onReset,
|
||||
isCurrentUserFrozen,
|
||||
}) => {
|
||||
const {
|
||||
loadPrivacySettings,
|
||||
@ -71,17 +76,19 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
||||
} = getActions();
|
||||
|
||||
useEffect(() => {
|
||||
loadBlockedUsers();
|
||||
loadPrivacySettings();
|
||||
loadContentSettings();
|
||||
loadWebAuthorizations();
|
||||
}, []);
|
||||
if (!isCurrentUserFrozen) {
|
||||
loadBlockedUsers();
|
||||
loadPrivacySettings();
|
||||
loadContentSettings();
|
||||
loadWebAuthorizations();
|
||||
}
|
||||
}, [isCurrentUserFrozen]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isActive) {
|
||||
if (isActive && !isCurrentUserFrozen) {
|
||||
loadGlobalPrivacySettings();
|
||||
}
|
||||
}, [isActive, loadGlobalPrivacySettings]);
|
||||
}, [isActive, isCurrentUserFrozen, loadGlobalPrivacySettings]);
|
||||
|
||||
const oldLang = useOldLang();
|
||||
const lang = useLang();
|
||||
@ -419,6 +426,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
|
||||
const { canDisplayChatInTitle } = selectSharedSettings(global);
|
||||
const shouldChargeForMessages = Boolean(nonContactPeersPaidStars);
|
||||
const isCurrentUserFrozen = selectIsCurrentUserFrozen(global);
|
||||
|
||||
return {
|
||||
isCurrentUserPremium: selectIsCurrentUserPremium(global),
|
||||
@ -435,6 +443,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
privacy,
|
||||
canDisplayChatInTitle,
|
||||
canSetPasscode: selectCanSetPasscode(global),
|
||||
isCurrentUserFrozen,
|
||||
};
|
||||
},
|
||||
)(SettingsPrivacy));
|
||||
|
||||
@ -19,6 +19,7 @@ import {
|
||||
selectChatFolder,
|
||||
selectChatMessage,
|
||||
selectCurrentMessageList,
|
||||
selectIsCurrentUserFrozen,
|
||||
selectIsCurrentUserPremium,
|
||||
selectIsForwardModalOpen,
|
||||
selectIsMediaViewerOpen,
|
||||
@ -141,6 +142,8 @@ type StateProps = {
|
||||
noRightColumnAnimation?: boolean;
|
||||
withInterfaceAnimations?: boolean;
|
||||
isSynced?: boolean;
|
||||
isAccountFrozen?: boolean;
|
||||
isAppConfigLoaded?: boolean;
|
||||
};
|
||||
|
||||
const APP_OUTDATED_TIMEOUT_MS = 5 * 60 * 1000; // 5 min
|
||||
@ -194,6 +197,8 @@ const Main = ({
|
||||
noRightColumnAnimation,
|
||||
isSynced,
|
||||
currentUserId,
|
||||
isAccountFrozen,
|
||||
isAppConfigLoaded,
|
||||
}: OwnProps & StateProps) => {
|
||||
const {
|
||||
initMain,
|
||||
@ -248,6 +253,10 @@ const Main = ({
|
||||
loadTopBotApps,
|
||||
loadPaidReactionPrivacy,
|
||||
loadPasswordInfo,
|
||||
loadBotFreezeAppeal,
|
||||
loadAllChats,
|
||||
loadAllStories,
|
||||
loadAllHiddenStories,
|
||||
} = getActions();
|
||||
|
||||
if (DEBUG && !DEBUG_isLogged) {
|
||||
@ -309,45 +318,54 @@ const Main = ({
|
||||
loadAppConfig();
|
||||
loadPeerColors();
|
||||
initMain();
|
||||
loadAvailableReactions();
|
||||
loadAnimatedEmojis();
|
||||
loadNotificationSettings();
|
||||
loadNotificationExceptions();
|
||||
loadAttachBots();
|
||||
loadContactList();
|
||||
loadDefaultTopicIcons();
|
||||
checkAppVersion();
|
||||
loadTopReactions();
|
||||
loadAuthorizations();
|
||||
loadPasswordInfo();
|
||||
}
|
||||
}, [isMasterTab, isSynced]);
|
||||
|
||||
// Initial API calls
|
||||
useEffect(() => {
|
||||
if (isMasterTab && isSynced && isAppConfigLoaded && !isAccountFrozen) {
|
||||
loadAllChats({ listType: 'saved' });
|
||||
loadAllStories();
|
||||
loadAllHiddenStories();
|
||||
loadRecentReactions();
|
||||
loadDefaultTagReactions();
|
||||
loadFeaturedEmojiStickers();
|
||||
loadAttachBots();
|
||||
loadNotificationSettings();
|
||||
loadNotificationExceptions();
|
||||
loadTopInlineBots();
|
||||
loadEmojiKeywords({ language: BASE_EMOJI_KEYWORD_LANG });
|
||||
loadTimezones();
|
||||
loadQuickReplies();
|
||||
loadTopReactions();
|
||||
loadStarStatus();
|
||||
loadEmojiKeywords({ language: BASE_EMOJI_KEYWORD_LANG });
|
||||
loadFeaturedEmojiStickers();
|
||||
loadSavedReactionTags();
|
||||
loadTopBotApps();
|
||||
loadPaidReactionPrivacy();
|
||||
loadDefaultTopicIcons();
|
||||
loadAnimatedEmojis();
|
||||
loadAvailableReactions();
|
||||
loadUserCollectibleStatuses();
|
||||
loadGenericEmojiEffects();
|
||||
loadPremiumGifts();
|
||||
loadStarGifts();
|
||||
loadAvailableEffects();
|
||||
loadBirthdayNumbersStickers();
|
||||
loadRestrictedEmojiStickers();
|
||||
loadGenericEmojiEffects();
|
||||
loadSavedReactionTags();
|
||||
loadAuthorizations();
|
||||
loadTopBotApps();
|
||||
loadPaidReactionPrivacy();
|
||||
loadPasswordInfo();
|
||||
loadUserCollectibleStatuses();
|
||||
loadQuickReplies();
|
||||
loadTimezones();
|
||||
}
|
||||
}, [isMasterTab, isSynced]);
|
||||
}, [isMasterTab, isSynced, isAppConfigLoaded, isAccountFrozen]);
|
||||
|
||||
// Initial Premium API calls
|
||||
useEffect(() => {
|
||||
if (isMasterTab && isCurrentUserPremium) {
|
||||
if (isMasterTab && isCurrentUserPremium && isAppConfigLoaded && !isAccountFrozen) {
|
||||
loadDefaultStatusIcons();
|
||||
loadRecentEmojiStatuses();
|
||||
}
|
||||
}, [isCurrentUserPremium, isMasterTab]);
|
||||
}, [isCurrentUserPremium, isMasterTab, isAppConfigLoaded, isAccountFrozen]);
|
||||
|
||||
// Language-based API calls
|
||||
useEffect(() => {
|
||||
@ -357,8 +375,6 @@ const Main = ({
|
||||
}
|
||||
|
||||
loadCountryList({ langCode: lang.code });
|
||||
|
||||
loadAttachBots();
|
||||
}
|
||||
}, [lang, isMasterTab]);
|
||||
|
||||
@ -374,7 +390,7 @@ const Main = ({
|
||||
|
||||
// Sticker sets
|
||||
useEffect(() => {
|
||||
if (isMasterTab && isSynced) {
|
||||
if (isMasterTab && isSynced && isAppConfigLoaded && !isAccountFrozen) {
|
||||
if (!addedSetIds || !addedCustomEmojiIds) {
|
||||
loadStickerSets();
|
||||
loadFavoriteStickers();
|
||||
@ -384,7 +400,11 @@ const Main = ({
|
||||
loadAddedStickers();
|
||||
}
|
||||
}
|
||||
}, [addedSetIds, addedCustomEmojiIds, isMasterTab, isSynced]);
|
||||
}, [addedSetIds, addedCustomEmojiIds, isMasterTab, isSynced, isAppConfigLoaded, isAccountFrozen]);
|
||||
|
||||
useEffect(() => {
|
||||
loadBotFreezeAppeal();
|
||||
}, [isAppConfigLoaded]);
|
||||
|
||||
// Check version when service chat is ready
|
||||
useEffect(() => {
|
||||
@ -636,6 +656,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
|| !selectCanAnimateInterface(global);
|
||||
|
||||
const deleteFolderDialog = deleteFolderDialogModal ? selectChatFolder(global, deleteFolderDialogModal) : undefined;
|
||||
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
||||
|
||||
return {
|
||||
currentUserId,
|
||||
@ -681,6 +702,8 @@ export default memo(withGlobal<OwnProps>(
|
||||
requestedDraft,
|
||||
noRightColumnAnimation,
|
||||
isSynced: global.isSynced,
|
||||
isAccountFrozen,
|
||||
isAppConfigLoaded: global.isAppConfigLoaded,
|
||||
};
|
||||
},
|
||||
)(Main));
|
||||
|
||||
21
src/components/middle/FrozenAccountPlaceholder.module.scss
Normal file
21
src/components/middle/FrozenAccountPlaceholder.module.scss
Normal file
@ -0,0 +1,21 @@
|
||||
.root {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.85;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
color: var(--color-error);
|
||||
font-weight: var(--font-weight-medium);
|
||||
font-size: 1rem;
|
||||
line-height: 1rem;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 0.875rem;
|
||||
margin-top: 0.25rem;
|
||||
line-height: 1rem;
|
||||
}
|
||||
29
src/components/middle/FrozenAccountPlaceholder.tsx
Normal file
29
src/components/middle/FrozenAccountPlaceholder.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import React, { memo } from '../../lib/teact/teact';
|
||||
import { getActions } from '../../global';
|
||||
|
||||
import useLang from '../../hooks/useLang';
|
||||
import useLastCallback from '../../hooks/useLastCallback';
|
||||
|
||||
import styles from './FrozenAccountPlaceholder.module.scss';
|
||||
|
||||
function FrozenAccountPlaceholder() {
|
||||
const lang = useLang();
|
||||
|
||||
const { openFrozenAccountModal } = getActions();
|
||||
|
||||
const handleClick = useLastCallback(() => {
|
||||
openFrozenAccountModal();
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
className={styles.root}
|
||||
onClick={handleClick}
|
||||
>
|
||||
<div className={styles.title}>{lang('ComposerTitleFrozenAccount')}</div>
|
||||
<div className={styles.subtitle}>{lang('ComposerSubtitleFrozenAccount')}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(FrozenAccountPlaceholder);
|
||||
@ -23,6 +23,7 @@ import {
|
||||
selectChatFullInfo,
|
||||
selectIsChatBotNotStarted,
|
||||
selectIsChatWithSelf,
|
||||
selectIsCurrentUserFrozen,
|
||||
selectIsInSelectMode,
|
||||
selectIsRightColumnShown,
|
||||
selectIsUserBlocked,
|
||||
@ -82,6 +83,7 @@ interface StateProps {
|
||||
language: string;
|
||||
detectedChatLanguage?: string;
|
||||
doNotTranslate: string[];
|
||||
isAccountFrozen?: boolean;
|
||||
}
|
||||
|
||||
// Chrome breaks layout when focusing input during transition
|
||||
@ -121,6 +123,7 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
|
||||
detectedChatLanguage,
|
||||
doNotTranslate,
|
||||
onTopicSearch,
|
||||
isAccountFrozen,
|
||||
}) => {
|
||||
const {
|
||||
joinChannel,
|
||||
@ -137,6 +140,7 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
|
||||
setSettingOption,
|
||||
unblockUser,
|
||||
setViewForumAsMessages,
|
||||
openFrozenAccountModal,
|
||||
} = getActions();
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
const menuButtonRef = useRef<HTMLButtonElement>(null);
|
||||
@ -219,6 +223,10 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const handleRequestCall = useLastCallback(() => {
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
return;
|
||||
}
|
||||
requestMasterAndRequestCall({ userId: chatId });
|
||||
});
|
||||
|
||||
@ -513,6 +521,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
|
||||
const isTranslating = Boolean(selectRequestedChatTranslationLanguage(global, chatId));
|
||||
const canTranslate = selectCanTranslateChat(global, chatId) && !fullInfo?.isTranslationDisabled;
|
||||
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
||||
|
||||
return {
|
||||
noMenu: false,
|
||||
@ -542,6 +551,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
doNotTranslate,
|
||||
detectedChatLanguage: chat.detectedLanguage,
|
||||
canUnblock,
|
||||
isAccountFrozen,
|
||||
};
|
||||
},
|
||||
)(HeaderActions));
|
||||
|
||||
@ -31,6 +31,7 @@ import {
|
||||
selectChatFullInfo,
|
||||
selectCurrentMessageList,
|
||||
selectIsChatWithSelf,
|
||||
selectIsCurrentUserFrozen,
|
||||
selectIsRightColumnShown,
|
||||
selectNotifyDefaults,
|
||||
selectNotifyException,
|
||||
@ -122,6 +123,7 @@ type StateProps = {
|
||||
isBot?: boolean;
|
||||
isChatWithSelf?: boolean;
|
||||
savedDialog?: ApiChat;
|
||||
isAccountFrozen?: boolean;
|
||||
};
|
||||
|
||||
const CLOSE_MENU_ANIMATION_DURATION = 200;
|
||||
@ -176,6 +178,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
onAsMessagesClick,
|
||||
onClose,
|
||||
onCloseAnimationEnd,
|
||||
isAccountFrozen,
|
||||
}) => {
|
||||
const {
|
||||
updateChatMutedState,
|
||||
@ -186,6 +189,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
createGroupCall,
|
||||
openLinkedChat,
|
||||
openAddContactDialog,
|
||||
openFrozenAccountModal,
|
||||
requestMasterAndRequestCall,
|
||||
toggleStatistics,
|
||||
openMonetizationStatistics,
|
||||
@ -224,14 +228,23 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const handleReport = useLastCallback(() => {
|
||||
setIsMenuOpen(false);
|
||||
reportMessages({ chatId, messageIds: [] });
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else {
|
||||
setIsMenuOpen(false);
|
||||
reportMessages({ chatId, messageIds: [] });
|
||||
}
|
||||
onClose();
|
||||
});
|
||||
|
||||
const handleDelete = useLastCallback(() => {
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
onClose();
|
||||
} else {
|
||||
setIsDeleteModalOpen(true);
|
||||
}
|
||||
setIsMenuOpen(false);
|
||||
setIsDeleteModalOpen(true);
|
||||
});
|
||||
|
||||
const closeMenu = useLastCallback(() => {
|
||||
@ -251,39 +264,68 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const handleStartBot = useLastCallback(() => {
|
||||
sendBotCommand({ command: '/start' });
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else {
|
||||
sendBotCommand({ command: '/start' });
|
||||
}
|
||||
});
|
||||
|
||||
const handleRestartBot = useLastCallback(() => {
|
||||
restartBot({ chatId });
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else {
|
||||
restartBot({ chatId });
|
||||
}
|
||||
});
|
||||
|
||||
const handleUnmuteClick = useLastCallback(() => {
|
||||
updateChatMutedState({ chatId, isMuted: false });
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else {
|
||||
updateChatMutedState({ chatId, isMuted: false });
|
||||
}
|
||||
closeMenu();
|
||||
});
|
||||
|
||||
const handleMuteClick = useLastCallback(() => {
|
||||
markRenderMuteModal();
|
||||
setIsMuteModalOpen(true);
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
closeMenu();
|
||||
} else {
|
||||
markRenderMuteModal();
|
||||
setIsMuteModalOpen(true);
|
||||
}
|
||||
setIsMenuOpen(false);
|
||||
});
|
||||
|
||||
const handleCreateTopicClick = useLastCallback(() => {
|
||||
openCreateTopicPanel({ chatId });
|
||||
setShouldCloseFast(!isRightColumnShown);
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else {
|
||||
openCreateTopicPanel({ chatId });
|
||||
setShouldCloseFast(!isRightColumnShown);
|
||||
}
|
||||
closeMenu();
|
||||
});
|
||||
|
||||
const handleEditClick = useLastCallback(() => {
|
||||
toggleManagement({ force: true });
|
||||
setShouldCloseFast(!isRightColumnShown);
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else {
|
||||
toggleManagement({ force: true });
|
||||
setShouldCloseFast(!isRightColumnShown);
|
||||
}
|
||||
closeMenu();
|
||||
});
|
||||
|
||||
const handleEditTopicClick = useLastCallback(() => {
|
||||
openEditTopicPanel({ chatId, topicId: Number(threadId) });
|
||||
setShouldCloseFast(!isRightColumnShown);
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else {
|
||||
openEditTopicPanel({ chatId, topicId: Number(threadId) });
|
||||
setShouldCloseFast(!isRightColumnShown);
|
||||
}
|
||||
closeMenu();
|
||||
});
|
||||
|
||||
@ -294,7 +336,9 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const handleEnterVoiceChatClick = useLastCallback(() => {
|
||||
if (canCreateVoiceChat) {
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else if (canCreateVoiceChat) {
|
||||
// TODO Show popup to schedule
|
||||
createGroupCall({
|
||||
chatId,
|
||||
@ -313,27 +357,47 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const handleGiftClick = useLastCallback(() => {
|
||||
openGiftModal({ forUserId: chatId });
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else {
|
||||
openGiftModal({ forUserId: chatId });
|
||||
}
|
||||
closeMenu();
|
||||
});
|
||||
|
||||
const handleAddContactClick = useLastCallback(() => {
|
||||
openAddContactDialog({ userId: chatId });
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else {
|
||||
openAddContactDialog({ userId: chatId });
|
||||
}
|
||||
closeMenu();
|
||||
});
|
||||
|
||||
const handleSubscribe = useLastCallback(() => {
|
||||
onSubscribeChannel();
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else {
|
||||
onSubscribeChannel();
|
||||
}
|
||||
closeMenu();
|
||||
});
|
||||
|
||||
const handleVideoCall = useLastCallback(() => {
|
||||
requestMasterAndRequestCall({ userId: chatId, isVideo: true });
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else {
|
||||
requestMasterAndRequestCall({ userId: chatId, isVideo: true });
|
||||
}
|
||||
closeMenu();
|
||||
});
|
||||
|
||||
const handleCall = useLastCallback(() => {
|
||||
requestMasterAndRequestCall({ userId: chatId });
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else {
|
||||
requestMasterAndRequestCall({ userId: chatId });
|
||||
}
|
||||
closeMenu();
|
||||
});
|
||||
|
||||
@ -355,7 +419,9 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const handleBoostClick = useLastCallback(() => {
|
||||
if (canViewBoosts) {
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else if (canViewBoosts) {
|
||||
openBoostStatistics({ chatId });
|
||||
setShouldCloseFast(!isRightColumnShown);
|
||||
} else {
|
||||
@ -370,7 +436,11 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const handleSelectMessages = useLastCallback(() => {
|
||||
enterMessageSelectMode();
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else {
|
||||
enterMessageSelectMode();
|
||||
}
|
||||
closeMenu();
|
||||
});
|
||||
|
||||
@ -380,12 +450,20 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const handleBlock = useLastCallback(() => {
|
||||
blockUser({ userId: chatId });
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else {
|
||||
blockUser({ userId: chatId });
|
||||
}
|
||||
closeMenu();
|
||||
});
|
||||
|
||||
const handleUnblock = useLastCallback(() => {
|
||||
unblockUser({ userId: chatId });
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
} else {
|
||||
unblockUser({ userId: chatId });
|
||||
}
|
||||
closeMenu();
|
||||
});
|
||||
|
||||
@ -756,6 +834,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
|
||||
const isSavedDialog = getIsSavedDialog(chatId, threadId, global.currentUserId);
|
||||
const savedDialog = isSavedDialog ? selectChat(global, String(threadId)) : undefined;
|
||||
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
||||
|
||||
return {
|
||||
chat,
|
||||
@ -782,6 +861,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
isBot: Boolean(chatBot),
|
||||
isChatWithSelf,
|
||||
savedDialog,
|
||||
isAccountFrozen,
|
||||
};
|
||||
},
|
||||
)(HeaderMenuContainer));
|
||||
|
||||
@ -43,6 +43,7 @@ import {
|
||||
selectFocusedMessageId,
|
||||
selectIsChatProtected,
|
||||
selectIsChatWithSelf,
|
||||
selectIsCurrentUserFrozen,
|
||||
selectIsCurrentUserPremium,
|
||||
selectIsInSelectMode,
|
||||
selectIsViewportNewest,
|
||||
@ -130,10 +131,12 @@ type StateProps = {
|
||||
isEmptyThread?: boolean;
|
||||
isForum?: boolean;
|
||||
currentUserId: string;
|
||||
isAccountFrozen?: boolean;
|
||||
areAdsEnabled?: boolean;
|
||||
channelJoinInfo?: ApiChatFullInfo['joinInfo'];
|
||||
isChatProtected?: boolean;
|
||||
hasCustomGreeting?: boolean;
|
||||
isAppConfigLoaded?: boolean;
|
||||
};
|
||||
|
||||
const MESSAGE_REACTIONS_POLLING_INTERVAL = 20 * 1000;
|
||||
@ -196,7 +199,9 @@ const MessageList: FC<OwnProps & StateProps> = ({
|
||||
onIntersectPinnedMessage,
|
||||
onScrollDownToggle,
|
||||
onNotchToggle,
|
||||
isAccountFrozen,
|
||||
hasCustomGreeting,
|
||||
isAppConfigLoaded,
|
||||
}) => {
|
||||
const {
|
||||
loadViewportMessages, setScrollOffset, loadSponsoredMessages, loadMessageReactions, copyMessagesByIds,
|
||||
@ -248,10 +253,10 @@ const MessageList: FC<OwnProps & StateProps> = ({
|
||||
|
||||
useEffect(() => {
|
||||
const canHaveAds = isChannelChat || isBot;
|
||||
if (areAdsEnabled && canHaveAds && isSynced && isReady) {
|
||||
if (areAdsEnabled && canHaveAds && isSynced && isReady && isAppConfigLoaded) {
|
||||
loadSponsoredMessages({ peerId: chatId });
|
||||
}
|
||||
}, [chatId, isSynced, isReady, isChannelChat, isBot, areAdsEnabled]);
|
||||
}, [chatId, isSynced, isReady, isChannelChat, isBot, areAdsEnabled, isAppConfigLoaded]);
|
||||
|
||||
// Updated only once when messages are loaded (as we want the unread divider to keep its position)
|
||||
useSyncEffect(() => {
|
||||
@ -344,7 +349,7 @@ const MessageList: FC<OwnProps & StateProps> = ({
|
||||
threadId, isChatWithSelf, channelJoinInfo]);
|
||||
|
||||
useInterval(() => {
|
||||
if (!messageIds || !messagesById || type === 'scheduled') return;
|
||||
if (!messageIds || !messagesById || type === 'scheduled' || isAccountFrozen) return;
|
||||
if (!isChannelChat && !isGroupChat) return;
|
||||
|
||||
const ids = messageIds.filter((id) => {
|
||||
@ -796,8 +801,10 @@ export default memo(withGlobal<OwnProps>(
|
||||
|
||||
const isCurrentUserPremium = selectIsCurrentUserPremium(global);
|
||||
const areAdsEnabled = !isCurrentUserPremium || selectUserFullInfo(global, currentUserId)?.areAdsEnabled;
|
||||
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
||||
|
||||
const hasCustomGreeting = Boolean(userFullInfo?.businessIntro);
|
||||
const isAppConfigLoaded = global.isAppConfigLoaded;
|
||||
|
||||
return {
|
||||
areAdsEnabled,
|
||||
@ -832,7 +839,9 @@ export default memo(withGlobal<OwnProps>(
|
||||
currentUserId,
|
||||
isChatProtected: selectIsChatProtected(global, chatId),
|
||||
...(withLastMessageWhenPreloading && { lastMessage }),
|
||||
isAccountFrozen,
|
||||
hasCustomGreeting,
|
||||
isAppConfigLoaded,
|
||||
};
|
||||
},
|
||||
)(MessageList));
|
||||
|
||||
@ -266,14 +266,19 @@
|
||||
}
|
||||
|
||||
.MessageSelectToolbar-inner,
|
||||
.composer-button,
|
||||
.messaging-disabled {
|
||||
.composer-button {
|
||||
.mask-image-disabled & {
|
||||
box-shadow: 0 0.25rem 0.5rem 0.125rem var(--color-default-shadow);
|
||||
border-radius: var(--border-radius-messages);
|
||||
}
|
||||
}
|
||||
|
||||
.messaging-disabled {
|
||||
.mask-image-disabled & {
|
||||
border-radius: var(--border-radius-messages);
|
||||
}
|
||||
}
|
||||
|
||||
.middle-column-footer-button-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
||||
@ -47,6 +47,7 @@ import {
|
||||
selectCurrentMiddleSearch,
|
||||
selectDraft,
|
||||
selectIsChatBotNotStarted,
|
||||
selectIsCurrentUserFrozen,
|
||||
selectIsInSelectMode,
|
||||
selectIsRightColumnShown,
|
||||
selectIsUserBlocked,
|
||||
@ -93,6 +94,7 @@ import ChatLanguageModal from './ChatLanguageModal.async';
|
||||
import { DropAreaState } from './composer/DropArea';
|
||||
import EmojiInteractionAnimation from './EmojiInteractionAnimation.async';
|
||||
import FloatingActionButtons from './FloatingActionButtons';
|
||||
import FrozenAccountPlaceholder from './FrozenAccountPlaceholder';
|
||||
import MessageList from './MessageList';
|
||||
import MessageSelectToolbar from './MessageSelectToolbar.async';
|
||||
import MiddleHeader from './MiddleHeader';
|
||||
@ -156,6 +158,8 @@ type StateProps = {
|
||||
isContactRequirePremium?: boolean;
|
||||
topics?: Record<number, ApiTopic>;
|
||||
paidMessagesStars?: number;
|
||||
isAccountFrozen?: boolean;
|
||||
freezeAppealChat?: ApiChat;
|
||||
};
|
||||
|
||||
function isImage(item: DataTransferItem) {
|
||||
@ -217,6 +221,8 @@ function MiddleColumn({
|
||||
isContactRequirePremium,
|
||||
topics,
|
||||
paidMessagesStars,
|
||||
isAccountFrozen,
|
||||
freezeAppealChat,
|
||||
}: OwnProps & StateProps) {
|
||||
const {
|
||||
openChat,
|
||||
@ -448,7 +454,8 @@ function MiddleColumn({
|
||||
|
||||
const composerRestrictionMessage = messageSendingRestrictionReason
|
||||
?? forumComposerPlaceholder
|
||||
?? (isContactRequirePremium ? <PremiumRequiredPlaceholder userId={chatId!} /> : undefined);
|
||||
?? (isContactRequirePremium ? <PremiumRequiredPlaceholder userId={chatId!} /> : undefined)
|
||||
?? (isAccountFrozen && freezeAppealChat?.id !== chatId ? <FrozenAccountPlaceholder /> : undefined);
|
||||
|
||||
// CSS Variables calculation doesn't work properly with transforms, so we calculate transform values in JS
|
||||
const {
|
||||
@ -477,7 +484,7 @@ function MiddleColumn({
|
||||
const isMessagingDisabled = Boolean(
|
||||
!isPinnedMessageList && !isSavedDialog && !renderingCanPost && !renderingCanRestartBot && !renderingCanStartBot
|
||||
&& !renderingCanSubscribe && composerRestrictionMessage,
|
||||
);
|
||||
) || (isAccountFrozen && freezeAppealChat?.id !== chatId);
|
||||
const withMessageListBottomShift = Boolean(
|
||||
renderingCanRestartBot || renderingCanSubscribe || renderingShouldSendJoinRequest || renderingCanStartBot
|
||||
|| (isPinnedMessageList && canUnpin) || canShowOpenChatButton || renderingCanUnblock,
|
||||
@ -809,6 +816,10 @@ export default memo(withGlobal<OwnProps>(
|
||||
|
||||
const isContactRequirePremium = userFull?.isContactRequirePremium;
|
||||
const paidMessagesStars = selectPeerPaidMessagesStars(global, chatId);
|
||||
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
||||
const botFreezeAppealId = global.botFreezeAppealId;
|
||||
const freezeAppealChat = botFreezeAppealId
|
||||
? selectChat(global, botFreezeAppealId) : undefined;
|
||||
|
||||
return {
|
||||
...state,
|
||||
@ -826,7 +837,8 @@ export default memo(withGlobal<OwnProps>(
|
||||
&& !isBotNotStarted
|
||||
&& !(shouldJoinToSend && chat?.isNotJoined)
|
||||
&& !shouldBlockSendInForum
|
||||
&& !isSavedDialog,
|
||||
&& !isSavedDialog
|
||||
&& (!isAccountFrozen || freezeAppealChat?.id === chatId),
|
||||
isPinnedMessageList,
|
||||
currentUserBannedRights: chat?.currentUserBannedRights,
|
||||
defaultBannedRights: chat?.defaultBannedRights,
|
||||
@ -847,6 +859,8 @@ export default memo(withGlobal<OwnProps>(
|
||||
isContactRequirePremium,
|
||||
topics,
|
||||
paidMessagesStars,
|
||||
isAccountFrozen,
|
||||
freezeAppealChat,
|
||||
};
|
||||
},
|
||||
)(MiddleColumn));
|
||||
|
||||
@ -19,6 +19,7 @@ import { getMessageReplyInfo } from '../../../global/helpers/replies';
|
||||
import {
|
||||
selectChat,
|
||||
selectChatMessage,
|
||||
selectIsCurrentUserFrozen,
|
||||
selectIsCurrentUserPremium,
|
||||
selectIsInSelectMode,
|
||||
selectIsMessageFocused,
|
||||
@ -86,6 +87,7 @@ type StateProps = {
|
||||
hasUnreadReaction?: boolean;
|
||||
isResizingContainer?: boolean;
|
||||
scrollTargetPosition?: ScrollTargetPosition;
|
||||
isAccountFrozen?: boolean;
|
||||
};
|
||||
|
||||
const SINGLE_LINE_ACTIONS: Set<ApiMessageAction['type']> = new Set([
|
||||
@ -121,6 +123,7 @@ const ActionMessage = ({
|
||||
observeIntersectionForBottom,
|
||||
observeIntersectionForLoading,
|
||||
observeIntersectionForPlaying,
|
||||
isAccountFrozen,
|
||||
}: OwnProps & StateProps) => {
|
||||
const {
|
||||
requestConfetti,
|
||||
@ -189,7 +192,7 @@ const ActionMessage = ({
|
||||
handleContextMenuClose, handleContextMenuHide,
|
||||
} = useContextMenuHandlers(
|
||||
ref,
|
||||
isTouchScreen && isInSelectMode,
|
||||
(isTouchScreen && isInSelectMode) || isAccountFrozen,
|
||||
!IS_ELECTRON,
|
||||
IS_ANDROID,
|
||||
getIsMessageListReady,
|
||||
@ -448,6 +451,7 @@ const ActionMessage = ({
|
||||
threadId={threadId}
|
||||
observeIntersection={observeIntersectionForPlaying}
|
||||
isCurrentUserPremium={isCurrentUserPremium}
|
||||
isAccountFrozen
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@ -479,6 +483,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
const isCurrentUserPremium = selectIsCurrentUserPremium(global);
|
||||
|
||||
const hasUnreadReaction = chat?.unreadReactions?.includes(message.id);
|
||||
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
||||
|
||||
return {
|
||||
sender,
|
||||
@ -494,6 +499,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
hasUnreadReaction,
|
||||
isResizingContainer,
|
||||
scrollTargetPosition,
|
||||
isAccountFrozen,
|
||||
};
|
||||
},
|
||||
)(ActionMessage));
|
||||
|
||||
@ -699,6 +699,31 @@ const ActionMessageText = ({
|
||||
case 'customAction':
|
||||
return action.message;
|
||||
|
||||
case 'paidMessagesPrice': {
|
||||
const { stars } = action;
|
||||
if (stars === 0) {
|
||||
return lang('ActionPaidMessageGroupPriceFree');
|
||||
}
|
||||
return lang('ActionPaidMessageGroupPrice', {
|
||||
stars: formatStarsAsText(lang, stars),
|
||||
}, { withNodes: true, withMarkdown: true });
|
||||
}
|
||||
|
||||
case 'paidMessagesRefunded': {
|
||||
const { stars } = action;
|
||||
const user = selectPeer(global, chatId);
|
||||
const userTitle = (user && getPeerTitle(lang, user)) || userFallbackText;
|
||||
|
||||
const key = isOutgoing
|
||||
? 'ApiMessageActionPaidMessagesRefundedOutgoing'
|
||||
: 'ApiMessageActionPaidMessagesRefundedIncoming';
|
||||
|
||||
return lang(key, {
|
||||
stars: formatStarsAsText(lang, stars),
|
||||
user: renderPeerLink(user?.id, userTitle),
|
||||
}, { withNodes: true, withMarkdown: true });
|
||||
}
|
||||
|
||||
case 'phoneCall': // Rendered as a regular message, but considered an action for the summary
|
||||
return lang(getCallMessageKey(action, isOutgoing));
|
||||
default:
|
||||
|
||||
@ -4,7 +4,7 @@ import { getActions, getGlobal } from '../../../global';
|
||||
|
||||
import type { ApiCommentsInfo } from '../../../api/types';
|
||||
|
||||
import { selectPeer } from '../../../global/selectors';
|
||||
import { selectIsCurrentUserFrozen, selectPeer } from '../../../global/selectors';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
import { formatIntegerCompact } from '../../../util/textFormat';
|
||||
|
||||
@ -36,7 +36,7 @@ const CommentButton: FC<OwnProps> = ({
|
||||
isLoading,
|
||||
asActionButton,
|
||||
}) => {
|
||||
const { openThread } = getActions();
|
||||
const { openThread, openFrozenAccountModal } = getActions();
|
||||
|
||||
const shouldRenderLoading = useAsyncRendering([isLoading], SHOW_LOADER_DELAY);
|
||||
|
||||
@ -46,6 +46,11 @@ const CommentButton: FC<OwnProps> = ({
|
||||
} = threadInfo;
|
||||
|
||||
const handleClick = useLastCallback(() => {
|
||||
const global = getGlobal();
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
openFrozenAccountModal();
|
||||
return;
|
||||
}
|
||||
openThread({
|
||||
isComments: true, chatId, originMessageId, originChannelId,
|
||||
});
|
||||
|
||||
@ -85,6 +85,7 @@ import {
|
||||
selectForwardedSender,
|
||||
selectIsChatProtected,
|
||||
selectIsChatWithSelf,
|
||||
selectIsCurrentUserFrozen,
|
||||
selectIsCurrentUserPremium,
|
||||
selectIsDocumentGroupSelected,
|
||||
selectIsInSelectMode,
|
||||
@ -305,6 +306,7 @@ type StateProps = {
|
||||
lastPlaybackTimestamp?: number;
|
||||
paidMessageStars?: number;
|
||||
isChatWithUser?: boolean;
|
||||
isAccountFrozen?: boolean;
|
||||
};
|
||||
|
||||
type MetaPosition =
|
||||
@ -428,6 +430,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
onIntersectPinnedMessage,
|
||||
paidMessageStars,
|
||||
isChatWithUser,
|
||||
isAccountFrozen,
|
||||
}) => {
|
||||
const {
|
||||
toggleMessageSelection,
|
||||
@ -465,7 +468,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
handleContextMenuHide,
|
||||
} = useContextMenuHandlers(
|
||||
ref,
|
||||
isTouchScreen && isInSelectMode,
|
||||
(isTouchScreen && isInSelectMode) || isAccountFrozen,
|
||||
!IS_ELECTRON,
|
||||
IS_ANDROID,
|
||||
getIsMessageListReady,
|
||||
@ -570,6 +573,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
const hasSubheader = hasTopicChip || hasMessageReply || hasStoryReply || hasForwardedCustomShape;
|
||||
|
||||
const selectMessage = useLastCallback((e?: React.MouseEvent<HTMLDivElement, MouseEvent>, groupedId?: string) => {
|
||||
if (isAccountFrozen) return;
|
||||
toggleMessageSelection({
|
||||
messageId,
|
||||
groupedId,
|
||||
@ -768,7 +772,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
&& !isInDocumentGroupNotLast && messageListType === 'thread'
|
||||
&& !noComments;
|
||||
const withQuickReactionButton = !isTouchScreen && !phoneCall && !isInSelectMode && defaultReaction
|
||||
&& !isInDocumentGroupNotLast && !isStoryMention && !hasTtl;
|
||||
&& !isInDocumentGroupNotLast && !isStoryMention && !hasTtl && !isAccountFrozen;
|
||||
|
||||
const hasOutsideReactions = !withVoiceTranscription && hasReactions
|
||||
&& (isCustomShape || ((photo || video || storyData || (location?.mediaType === 'geo')) && !hasText));
|
||||
@ -1048,6 +1052,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
noRecentReactors={isChannel}
|
||||
tags={tags}
|
||||
isCurrentUserPremium={isPremium}
|
||||
isAccountFrozen
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -1699,6 +1704,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
observeIntersection={observeIntersectionForPlaying}
|
||||
noRecentReactors={isChannel}
|
||||
tags={tags}
|
||||
isAccountFrozen
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@ -1858,6 +1864,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
const maxTimestamp = selectMessageTimestampableDuration(global, message);
|
||||
|
||||
const lastPlaybackTimestamp = selectMessageLastPlaybackTimestamp(global, chatId, message.id);
|
||||
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
||||
|
||||
return {
|
||||
theme: selectTheme(global),
|
||||
@ -1951,6 +1958,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
lastPlaybackTimestamp,
|
||||
paidMessageStars,
|
||||
isChatWithUser,
|
||||
isAccountFrozen,
|
||||
};
|
||||
},
|
||||
)(Message));
|
||||
|
||||
@ -36,6 +36,7 @@ type OwnProps = {
|
||||
isCurrentUserPremium?: boolean;
|
||||
observeIntersection?: ObserveFn;
|
||||
noRecentReactors?: boolean;
|
||||
isAccountFrozen?: boolean;
|
||||
};
|
||||
|
||||
const MAX_RECENT_AVATARS = 3;
|
||||
@ -51,6 +52,7 @@ const Reactions: FC<OwnProps> = ({
|
||||
noRecentReactors,
|
||||
isCurrentUserPremium,
|
||||
tags,
|
||||
isAccountFrozen,
|
||||
}) => {
|
||||
const {
|
||||
toggleReaction,
|
||||
@ -60,6 +62,7 @@ const Reactions: FC<OwnProps> = ({
|
||||
openPremiumModal,
|
||||
resetLocalPaidReactions,
|
||||
showNotification,
|
||||
openFrozenAccountModal,
|
||||
} = getActions();
|
||||
const lang = useOldLang();
|
||||
|
||||
@ -107,6 +110,10 @@ const Reactions: FC<OwnProps> = ({
|
||||
}, [message, noRecentReactors, recentReactorsByReactionKey, results, areTags, tags, totalCount]);
|
||||
|
||||
const handleClick = useLastCallback((reaction: ApiReaction) => {
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
return;
|
||||
}
|
||||
if (areTags) {
|
||||
if (!isCurrentUserPremium) {
|
||||
openPremiumModal({
|
||||
@ -130,6 +137,11 @@ const Reactions: FC<OwnProps> = ({
|
||||
const paidLocalCount = useMemo(() => results.find((r) => r.reaction.type === 'paid')?.localAmount || 0, [results]);
|
||||
|
||||
const handlePaidClick = useLastCallback((count: number) => {
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
return;
|
||||
}
|
||||
|
||||
addLocalPaidReaction({
|
||||
chatId: message.chatId,
|
||||
messageId: message.id,
|
||||
@ -162,6 +174,11 @@ const Reactions: FC<OwnProps> = ({
|
||||
}, [lang, message, paidLocalCount]);
|
||||
|
||||
const handleRemoveReaction = useLastCallback((reaction: ApiReaction) => {
|
||||
if (isAccountFrozen) {
|
||||
openFrozenAccountModal();
|
||||
return;
|
||||
}
|
||||
|
||||
toggleReaction({
|
||||
chatId: message.chatId,
|
||||
messageId: message.id,
|
||||
|
||||
@ -15,6 +15,7 @@ import ChatInviteModal from './chatInvite/ChatInviteModal.async';
|
||||
import ChatlistModal from './chatlist/ChatlistModal.async';
|
||||
import CollectibleInfoModal from './collectible/CollectibleInfoModal.async';
|
||||
import EmojiStatusAccessModal from './emojiStatusAccess/EmojiStatusAccessModal.async';
|
||||
import FrozenAccountModal from './frozenAccount/FrozenAccountModal.async';
|
||||
import PremiumGiftModal from './gift/GiftModal.async';
|
||||
import GiftInfoModal from './gift/info/GiftInfoModal.async';
|
||||
import GiftRecipientPicker from './gift/recipient/GiftRecipientPicker.async';
|
||||
@ -79,7 +80,8 @@ type ModalKey = keyof Pick<TabState,
|
||||
'sharePreparedMessageModal' |
|
||||
'giftStatusInfoModal' |
|
||||
'giftTransferModal' |
|
||||
'chatRefundModal'
|
||||
'chatRefundModal' |
|
||||
'isFrozenAccountModalOpen'
|
||||
>;
|
||||
|
||||
type StateProps = {
|
||||
@ -130,6 +132,7 @@ const MODALS: ModalRegistry = {
|
||||
sharePreparedMessageModal: SharePreparedMessageModal,
|
||||
giftTransferModal: GiftTransferModal,
|
||||
chatRefundModal: ChatRefundModal,
|
||||
isFrozenAccountModalOpen: FrozenAccountModal,
|
||||
};
|
||||
const MODAL_KEYS = Object.keys(MODALS) as ModalKey[];
|
||||
const MODAL_ENTRIES = Object.entries(MODALS) as Entries<ModalRegistry>;
|
||||
|
||||
@ -9,7 +9,9 @@ import type { ApiStickerSet, ApiUser } from '../../../api/types';
|
||||
import type { TabState } from '../../../global/types';
|
||||
|
||||
import { getUserFullName } from '../../../global/helpers';
|
||||
import { selectIsCurrentUserPremium, selectStickerSet, selectUser } from '../../../global/selectors';
|
||||
import {
|
||||
selectIsCurrentUserFrozen, selectIsCurrentUserPremium, selectStickerSet, selectUser,
|
||||
} from '../../../global/selectors';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
|
||||
import useInterval from '../../../hooks/schedulers/useInterval';
|
||||
@ -31,6 +33,7 @@ export type StateProps = {
|
||||
currentUser?: ApiUser;
|
||||
stickerSet?: ApiStickerSet;
|
||||
isPremium?: boolean;
|
||||
isAccountFrozen?: boolean;
|
||||
};
|
||||
|
||||
const INTERVAL = 3200;
|
||||
@ -40,6 +43,7 @@ const EmojiStatusAccessModal: FC<OwnProps & StateProps> = ({
|
||||
currentUser,
|
||||
stickerSet,
|
||||
isPremium,
|
||||
isAccountFrozen,
|
||||
}) => {
|
||||
const {
|
||||
closeEmojiStatusAccessModal,
|
||||
@ -60,10 +64,10 @@ const EmojiStatusAccessModal: FC<OwnProps & StateProps> = ({
|
||||
const [currentStatusIndex, setCurrentStatusIndex] = useState<number>(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen && !stickerSet?.stickers) {
|
||||
if (isOpen && !stickerSet?.stickers && !isAccountFrozen) {
|
||||
loadDefaultStatusIcons();
|
||||
}
|
||||
}, [isOpen, stickerSet]);
|
||||
}, [isOpen, stickerSet, isAccountFrozen]);
|
||||
|
||||
const mockPeerWithStatus = useMemo(() => {
|
||||
if (!currentUser || !stickerSet?.stickers) return undefined;
|
||||
@ -195,11 +199,13 @@ export default memo(withGlobal<OwnProps>(
|
||||
const currentUser = selectUser(global, global.currentUserId!);
|
||||
const isPremium = selectIsCurrentUserPremium(global);
|
||||
const stickerSet = global.defaultStatusIconsId ? selectStickerSet(global, global.defaultStatusIconsId) : undefined;
|
||||
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
||||
|
||||
return {
|
||||
currentUser,
|
||||
stickerSet,
|
||||
isPremium,
|
||||
isAccountFrozen,
|
||||
};
|
||||
},
|
||||
)(EmojiStatusAccessModal));
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
import type { FC } from '../../../lib/teact/teact';
|
||||
import React from '../../../lib/teact/teact';
|
||||
|
||||
import type { OwnProps } from './FrozenAccountModal';
|
||||
|
||||
import { Bundles } from '../../../util/moduleLoader';
|
||||
|
||||
import useModuleLoader from '../../../hooks/useModuleLoader';
|
||||
|
||||
const FrozenAccountModalAsync: FC<OwnProps> = (props) => {
|
||||
const { modal } = props;
|
||||
const FrozenAccountModal = useModuleLoader(Bundles.Extra, 'FrozenAccountModal', modal);
|
||||
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
return FrozenAccountModal ? <FrozenAccountModal {...props} /> : undefined;
|
||||
};
|
||||
|
||||
export default FrozenAccountModalAsync;
|
||||
@ -0,0 +1,26 @@
|
||||
.header {
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: var(--font-weight-medium);
|
||||
font-size: 1.25rem;
|
||||
text-align: center;
|
||||
padding-top: 0.5rem;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 0.5rem;
|
||||
display: flex;
|
||||
align-self: stretch;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.buttonAppeal {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
143
src/components/modals/frozenAccount/FrozenAccountModal.tsx
Normal file
143
src/components/modals/frozenAccount/FrozenAccountModal.tsx
Normal file
@ -0,0 +1,143 @@
|
||||
import React, { memo, useMemo } from '../../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../../global';
|
||||
|
||||
import type { TabState } from '../../../global/types';
|
||||
|
||||
import { selectUser } from '../../../global/selectors';
|
||||
import { formatDateToString } from '../../../util/dates/dateFormat';
|
||||
import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets';
|
||||
import formatUsername from '../../common/helpers/formatUsername';
|
||||
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useLastCallback from '../../../hooks/useLastCallback';
|
||||
|
||||
import AnimatedIconWithPreview from '../../common/AnimatedIconWithPreview';
|
||||
import Button from '../../ui/Button';
|
||||
import Link from '../../ui/Link';
|
||||
import TableAboutModal, { type TableAboutData } from '../common/TableAboutModal';
|
||||
|
||||
import styles from './FrozenAccountModal.module.scss';
|
||||
|
||||
export type OwnProps = {
|
||||
modal: TabState['isFrozenAccountModalOpen'];
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
freezeAppealUrl?: string;
|
||||
botFreezeAppealUsername?: string;
|
||||
freezeUntilDate?: number;
|
||||
};
|
||||
|
||||
const FrozenAccountModal = ({
|
||||
modal,
|
||||
freezeUntilDate,
|
||||
freezeAppealUrl,
|
||||
botFreezeAppealUsername,
|
||||
}: OwnProps & StateProps) => {
|
||||
const {
|
||||
closeFrozenAccountModal,
|
||||
openUrl,
|
||||
} = getActions();
|
||||
const lang = useLang();
|
||||
|
||||
const isOpen = Boolean(modal);
|
||||
|
||||
const handleClose = useLastCallback(() => {
|
||||
closeFrozenAccountModal();
|
||||
});
|
||||
|
||||
const handleAppeal = useLastCallback(() => {
|
||||
closeFrozenAccountModal();
|
||||
if (freezeAppealUrl) {
|
||||
openUrl({ url: freezeAppealUrl });
|
||||
}
|
||||
});
|
||||
|
||||
const header = useMemo(() => {
|
||||
return (
|
||||
<div className={styles.header}>
|
||||
<AnimatedIconWithPreview
|
||||
size={160}
|
||||
tgsUrl={LOCAL_TGS_URLS.BannedDuck}
|
||||
noLoop
|
||||
/>
|
||||
<div className={styles.title}>
|
||||
{lang('FrozenAccountModalTitle')}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}, [lang]);
|
||||
|
||||
const footer = useMemo(() => {
|
||||
if (!isOpen) return undefined;
|
||||
return (
|
||||
<div className={styles.footer}>
|
||||
<Button
|
||||
className={styles.buttonAppeal}
|
||||
size="smaller"
|
||||
onClick={handleAppeal}
|
||||
noForcedUpperCase
|
||||
>
|
||||
{lang('ButtonAppeal')}
|
||||
</Button>
|
||||
<Button
|
||||
isText
|
||||
size="smaller"
|
||||
onClick={handleClose}
|
||||
noForcedUpperCase
|
||||
>
|
||||
{lang('ButtonUnderstood')}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}, [lang, isOpen]);
|
||||
|
||||
if (!freezeUntilDate || !botFreezeAppealUsername) return undefined;
|
||||
|
||||
const date = new Date(freezeUntilDate * 1000);
|
||||
|
||||
const botLink = (
|
||||
<Link onClick={handleAppeal} isPrimary>
|
||||
{formatUsername(botFreezeAppealUsername)}
|
||||
</Link>
|
||||
);
|
||||
|
||||
const listItemData = [
|
||||
['hand-stop', lang('FrozenAccountViolationTitle'), lang('FrozenAccountViolationSubtitle')],
|
||||
['lock', lang('FrozenAccountReadOnlyTitle'), lang('FrozenAccountReadOnlySubtitle')],
|
||||
['frozen-time', lang('FrozenAccountAppealTitle'),
|
||||
lang('FrozenAccountAppealSubtitle', {
|
||||
botLink,
|
||||
date: formatDateToString(date, lang.code),
|
||||
}, {
|
||||
withNodes: true,
|
||||
})],
|
||||
] satisfies TableAboutData;
|
||||
|
||||
return (
|
||||
<TableAboutModal
|
||||
isOpen={isOpen}
|
||||
header={header}
|
||||
listItemData={listItemData}
|
||||
footer={footer}
|
||||
hasBackdrop
|
||||
onClose={handleClose}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global): StateProps => {
|
||||
const freezeUntilDate = global.appConfig?.freezeUntilDate;
|
||||
const freezeAppealUrl = global.appConfig?.freezeAppealUrl;
|
||||
const botFreezeAppealId = global.botFreezeAppealId;
|
||||
const botFreezeAppealUsername = botFreezeAppealId
|
||||
? selectUser(global, botFreezeAppealId)?.usernames?.[0]?.username : undefined;
|
||||
|
||||
return {
|
||||
freezeUntilDate,
|
||||
freezeAppealUrl,
|
||||
botFreezeAppealUsername,
|
||||
};
|
||||
},
|
||||
)(FrozenAccountModal));
|
||||
@ -19,6 +19,7 @@ import { isChatChannel, isUserId } from '../../global/helpers';
|
||||
import { getPeerTitle } from '../../global/helpers/peers';
|
||||
import {
|
||||
selectChat,
|
||||
selectIsCurrentUserFrozen,
|
||||
selectIsCurrentUserPremium,
|
||||
selectPeer,
|
||||
selectPeerPaidMessagesStars,
|
||||
@ -104,6 +105,7 @@ interface StateProps {
|
||||
stealthMode: ApiStealthMode;
|
||||
withHeaderAnimation?: boolean;
|
||||
paidMessagesStars?: number;
|
||||
isAccountFrozen?: boolean;
|
||||
}
|
||||
|
||||
const VIDEO_MIN_READY_STATE = IS_SAFARI ? 4 : 3;
|
||||
@ -137,6 +139,7 @@ function Story({
|
||||
onClose,
|
||||
onReport,
|
||||
paidMessagesStars,
|
||||
isAccountFrozen,
|
||||
}: OwnProps & StateProps) {
|
||||
const {
|
||||
viewStory,
|
||||
@ -233,7 +236,7 @@ function Story({
|
||||
? story.content.video.duration
|
||||
: undefined;
|
||||
|
||||
const shouldShowComposer = !(isOut && isUserStory) && !isChangelog && !isChannelStory;
|
||||
const shouldShowComposer = !(isOut && isUserStory) && !isChangelog && !isChannelStory && !isAccountFrozen;
|
||||
const shouldShowFooter = isLoadedStory && !shouldShowComposer && (isOut || isChannelStory);
|
||||
const headerAnimation = isMobile && withHeaderAnimation ? 'slideFade' : 'none';
|
||||
|
||||
@ -965,6 +968,7 @@ export default memo(withGlobal<OwnProps>((global, {
|
||||
|
||||
const fromPeer = isLoadedStory && story.fromId ? selectPeer(global, story.fromId) : undefined;
|
||||
const paidMessagesStars = selectPeerPaidMessagesStars(global, peerId);
|
||||
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
||||
|
||||
return {
|
||||
peer: (user || chat)!,
|
||||
@ -982,5 +986,6 @@ export default memo(withGlobal<OwnProps>((global, {
|
||||
stealthMode: global.stories.stealthMode,
|
||||
withHeaderAnimation,
|
||||
paidMessagesStars,
|
||||
isAccountFrozen,
|
||||
};
|
||||
})(Story));
|
||||
|
||||
@ -23,6 +23,7 @@ import './ui/messages';
|
||||
import './ui/globalSearch';
|
||||
import './ui/middleSearch';
|
||||
import './ui/stickerSearch';
|
||||
import './ui/account';
|
||||
import './ui/users';
|
||||
import './ui/settings';
|
||||
import './ui/misc';
|
||||
|
||||
@ -16,6 +16,7 @@ import { ManagementProgress } from '../../../types';
|
||||
|
||||
import { BOT_FATHER_USERNAME, GENERAL_REFETCH_INTERVAL, PAID_SEND_DELAY } from '../../../config';
|
||||
import { copyTextToClipboard } from '../../../util/clipboard';
|
||||
import { getUsernameFromDeepLink } from '../../../util/deepLinkParser';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { getTranslationFn } from '../../../util/localization';
|
||||
import { formatStarsAsText } from '../../../util/localization/format';
|
||||
@ -55,6 +56,7 @@ import {
|
||||
selectCurrentChat,
|
||||
selectCurrentMessageList,
|
||||
selectDraft,
|
||||
selectIsCurrentUserFrozen,
|
||||
selectIsTrustedBot,
|
||||
selectMessageReplyInfo,
|
||||
selectPeer,
|
||||
@ -681,6 +683,11 @@ addActionHandler('requestMainWebView', async (global, actions, payload): Promise
|
||||
tabId = getCurrentTabId(),
|
||||
} = payload;
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
actions.openFrozenAccountModal({ tabId });
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkIfOpenOrActivate(global, botId, tabId)) return;
|
||||
|
||||
const bot = selectUser(global, botId);
|
||||
@ -1423,3 +1430,17 @@ addActionHandler('startBotFatherConversation', async (global, actions, payload):
|
||||
|
||||
actions.openChat({ id: botFatherId, tabId });
|
||||
});
|
||||
|
||||
addActionHandler('loadBotFreezeAppeal', async (global): Promise<void> => {
|
||||
const botUrl = global.appConfig?.freezeAppealUrl;
|
||||
if (!botUrl) return;
|
||||
const botAppealUsername = botUrl ? getUsernameFromDeepLink(botUrl) : undefined;
|
||||
if (!botAppealUsername) return;
|
||||
const chat = await fetchChatByUsername(global, botAppealUsername);
|
||||
global = getGlobal();
|
||||
global = {
|
||||
...global,
|
||||
botFreezeAppealId: chat?.id,
|
||||
};
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
@ -113,6 +113,7 @@ import {
|
||||
selectDraft,
|
||||
selectIsChatPinned,
|
||||
selectIsChatWithSelf,
|
||||
selectIsCurrentUserFrozen,
|
||||
selectLastServiceNotification,
|
||||
selectPeer,
|
||||
selectSimilarChannelIds,
|
||||
@ -366,10 +367,11 @@ addActionHandler('openThread', async (global, actions, payload): Promise<void> =
|
||||
});
|
||||
}
|
||||
|
||||
const result = await callApi('fetchDiscussionMessage', {
|
||||
chat: selectChat(global, loadingChatId)!,
|
||||
messageId: Number(loadingThreadId),
|
||||
});
|
||||
const result = selectIsCurrentUserFrozen(global) ? undefined
|
||||
: await callApi('fetchDiscussionMessage', {
|
||||
chat: selectChat(global, loadingChatId)!,
|
||||
messageId: Number(loadingThreadId),
|
||||
});
|
||||
|
||||
global = getGlobal();
|
||||
loadingThread = selectTabState(global, tabId).loadingThread;
|
||||
@ -630,6 +632,11 @@ addActionHandler('updateChatMutedState', (global, actions, payload): ActionRetur
|
||||
const { chatId, isMuted } = payload;
|
||||
let { mutedUntil } = payload;
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
actions.openFrozenAccountModal({ tabId: getCurrentTabId() });
|
||||
return;
|
||||
}
|
||||
|
||||
const chat = selectChat(global, chatId);
|
||||
if (!chat) {
|
||||
return;
|
||||
@ -911,6 +918,11 @@ addActionHandler('createGroupChat', async (global, actions, payload): Promise<vo
|
||||
|
||||
addActionHandler('toggleChatPinned', (global, actions, payload): ActionReturnType => {
|
||||
const { id, folderId, tabId = getCurrentTabId() } = payload;
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
actions.openFrozenAccountModal({ tabId });
|
||||
return;
|
||||
}
|
||||
const chat = selectChat(global, id);
|
||||
if (!chat) {
|
||||
return;
|
||||
@ -958,6 +970,12 @@ addActionHandler('toggleChatPinned', (global, actions, payload): ActionReturnTyp
|
||||
|
||||
addActionHandler('toggleChatArchived', (global, actions, payload): ActionReturnType => {
|
||||
const { id } = payload;
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
actions.openFrozenAccountModal({ tabId: getCurrentTabId() });
|
||||
return;
|
||||
}
|
||||
|
||||
const chat = selectChat(global, id);
|
||||
if (chat) {
|
||||
void callApi('toggleChatArchived', {
|
||||
@ -969,6 +987,12 @@ addActionHandler('toggleChatArchived', (global, actions, payload): ActionReturnT
|
||||
|
||||
addActionHandler('toggleSavedDialogPinned', (global, actions, payload): ActionReturnType => {
|
||||
const { id, tabId = getCurrentTabId() } = payload;
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
actions.openFrozenAccountModal({ tabId });
|
||||
return;
|
||||
}
|
||||
|
||||
const chat = selectChat(global, id);
|
||||
if (!chat) {
|
||||
return;
|
||||
@ -1171,6 +1195,11 @@ addActionHandler('deleteChatFolder', async (global, actions, payload): Promise<v
|
||||
|
||||
addActionHandler('markChatUnread', (global, actions, payload): ActionReturnType => {
|
||||
const { id } = payload;
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
actions.openFrozenAccountModal({ tabId: getCurrentTabId() });
|
||||
return;
|
||||
}
|
||||
const chat = selectChat(global, id);
|
||||
if (!chat) return;
|
||||
void callApi('toggleDialogUnread', {
|
||||
@ -1180,7 +1209,14 @@ addActionHandler('markChatUnread', (global, actions, payload): ActionReturnType
|
||||
});
|
||||
|
||||
addActionHandler('markChatMessagesRead', async (global, actions, payload): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
const { id } = payload;
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
actions.openFrozenAccountModal({ tabId: getCurrentTabId() });
|
||||
return;
|
||||
}
|
||||
|
||||
const chat = selectChat(global, id);
|
||||
if (!chat) return;
|
||||
if (!chat.isForum) {
|
||||
@ -1229,6 +1265,7 @@ addActionHandler('markChatRead', (global, actions, payload): ActionReturnType =>
|
||||
});
|
||||
|
||||
addActionHandler('markTopicRead', (global, actions, payload): ActionReturnType => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
const { chatId, topicId } = payload;
|
||||
const chat = selectChat(global, chatId);
|
||||
if (!chat) return;
|
||||
@ -1784,6 +1821,8 @@ addActionHandler('updateChatMemberBannedRights', async (global, actions, payload
|
||||
});
|
||||
|
||||
addActionHandler('updateChatAdmin', async (global, actions, payload): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const {
|
||||
chatId, userId, adminRights, customTitle,
|
||||
tabId = getCurrentTabId(),
|
||||
@ -1942,6 +1981,7 @@ addActionHandler('loadGroupsForDiscussion', async (global): Promise<void> => {
|
||||
});
|
||||
|
||||
addActionHandler('linkDiscussionGroup', async (global, actions, payload): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
const { channelId, chatId, tabId = getCurrentTabId() } = payload || {};
|
||||
|
||||
const channel = selectChat(global, channelId);
|
||||
@ -2023,6 +2063,7 @@ addActionHandler('resetOpenChatWithDraft', (global, actions, payload): ActionRet
|
||||
});
|
||||
|
||||
addActionHandler('loadMoreMembers', async (global, actions, payload): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
const { tabId = getCurrentTabId() } = payload || {};
|
||||
const { chatId } = selectCurrentMessageList(global, tabId) || {};
|
||||
const chat = chatId ? selectChat(global, chatId) : undefined;
|
||||
@ -2211,7 +2252,11 @@ addActionHandler('processAttachBotParameters', async (global, actions, payload):
|
||||
});
|
||||
|
||||
addActionHandler('loadTopics', async (global, actions, payload): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
const { chatId, force } = payload;
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
return;
|
||||
}
|
||||
const chat = selectChat(global, chatId);
|
||||
if (!chat) return;
|
||||
|
||||
@ -2780,6 +2825,8 @@ addActionHandler('setViewForumAsMessages', (global, actions, payload): ActionRet
|
||||
});
|
||||
|
||||
addActionHandler('loadChannelRecommendations', async (global, actions, payload): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const { chatId } = payload;
|
||||
const chat = chatId ? selectChat(global, chatId) : undefined;
|
||||
|
||||
@ -2810,6 +2857,8 @@ addActionHandler('loadChannelRecommendations', async (global, actions, payload):
|
||||
});
|
||||
|
||||
addActionHandler('loadBotRecommendations', async (global, actions, payload): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const { userId } = payload;
|
||||
const user = selectChat(global, userId);
|
||||
|
||||
@ -2915,20 +2964,21 @@ async function loadChats(
|
||||
|
||||
const isFirstBatch = !shouldIgnorePagination && !offsetPeer && !offsetDate && !offsetId;
|
||||
const shouldReplaceStaleState = listType === 'active' && isFirstBatch;
|
||||
const isAccountFreeze = selectIsCurrentUserFrozen(global);
|
||||
|
||||
const result = listType === 'saved' ? await callApi('fetchSavedChats', {
|
||||
limit: CHAT_LIST_LOAD_SLICE,
|
||||
offsetDate,
|
||||
offsetId,
|
||||
offsetPeer,
|
||||
withPinned: isFirstBatch,
|
||||
withPinned: isFirstBatch && !isAccountFreeze,
|
||||
}) : await callApi('fetchChats', {
|
||||
limit: CHAT_LIST_LOAD_SLICE,
|
||||
offsetDate,
|
||||
offsetId,
|
||||
offsetPeer,
|
||||
archived: listType === 'archived',
|
||||
withPinned: isFirstBatch,
|
||||
withPinned: isFirstBatch && !isAccountFreeze,
|
||||
lastLocalServiceMessageId,
|
||||
});
|
||||
|
||||
@ -3002,6 +3052,7 @@ async function loadChats(
|
||||
export async function loadFullChat<T extends GlobalState>(
|
||||
global: T, actions: RequiredGlobalActions, chat: ApiChat,
|
||||
) {
|
||||
if (selectIsCurrentUserFrozen(global)) return undefined;
|
||||
const result = await callApi('fetchFullChat', chat);
|
||||
if (!result) {
|
||||
return undefined;
|
||||
|
||||
@ -10,7 +10,8 @@ import {
|
||||
updateChat, updateChatFullInfo, updateManagement, updateManagementProgress, updateUserFullInfo,
|
||||
} from '../../reducers';
|
||||
import {
|
||||
selectChat, selectCurrentMessageList, selectTabState, selectUser,
|
||||
selectChat, selectCurrentMessageList, selectIsCurrentUserFrozen,
|
||||
selectTabState, selectUser,
|
||||
} from '../../selectors';
|
||||
import { ensureIsSuperGroup } from './chats';
|
||||
|
||||
@ -109,6 +110,8 @@ addActionHandler('setOpenedInviteInfo', (global, actions, payload): ActionReturn
|
||||
});
|
||||
|
||||
addActionHandler('loadExportedChatInvites', async (global, actions, payload): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const {
|
||||
chatId, adminId, isRevoked, limit, tabId = getCurrentTabId(),
|
||||
} = payload!;
|
||||
|
||||
@ -120,6 +120,7 @@ import {
|
||||
selectForwardsContainVoiceMessages,
|
||||
selectIsChatBotNotStarted,
|
||||
selectIsChatWithSelf,
|
||||
selectIsCurrentUserFrozen,
|
||||
selectIsCurrentUserPremium,
|
||||
selectLanguageCode,
|
||||
selectListedIds,
|
||||
@ -994,6 +995,7 @@ addActionHandler('reportChannelSpam', (global, actions, payload): ActionReturnTy
|
||||
});
|
||||
|
||||
addActionHandler('markMessageListRead', (global, actions, payload): ActionReturnType => {
|
||||
if (selectIsCurrentUserFrozen(global)) return undefined;
|
||||
const { maxId, tabId = getCurrentTabId() } = payload!;
|
||||
|
||||
const currentMessageList = selectCurrentMessageList(global, tabId);
|
||||
@ -1177,6 +1179,8 @@ addActionHandler('loadExtendedMedia', (global, actions, payload): ActionReturnTy
|
||||
});
|
||||
|
||||
addActionHandler('loadScheduledHistory', async (global, actions, payload): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const { chatId } = payload;
|
||||
const chat = selectChat(global, chatId);
|
||||
if (!chat) {
|
||||
@ -1852,6 +1856,8 @@ addActionHandler('loadSendPaidReactionsAs', async (global, actions, payload): Pr
|
||||
});
|
||||
|
||||
addActionHandler('loadSponsoredMessages', async (global, actions, payload): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const { peerId } = payload;
|
||||
const peer = selectPeer(global, peerId);
|
||||
if (!peer) {
|
||||
@ -1880,7 +1886,7 @@ addActionHandler('viewSponsoredMessage', (global, actions, payload): ActionRetur
|
||||
return;
|
||||
}
|
||||
|
||||
void callApi('viewSponsoredMessage', { peer, random: message.randomId });
|
||||
void callApi('viewSponsoredMessage', { random: message.randomId });
|
||||
});
|
||||
|
||||
addActionHandler('clickSponsoredMessage', (global, actions, payload): ActionReturnType => {
|
||||
@ -1892,7 +1898,7 @@ addActionHandler('clickSponsoredMessage', (global, actions, payload): ActionRetu
|
||||
}
|
||||
|
||||
void callApi('clickSponsoredMessage', {
|
||||
peer, random: message.randomId, isMedia, isFullscreen,
|
||||
random: message.randomId, isMedia, isFullscreen,
|
||||
});
|
||||
});
|
||||
|
||||
@ -1905,7 +1911,7 @@ addActionHandler('reportSponsoredMessage', async (global, actions, payload): Pro
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await callApi('reportSponsoredMessage', { peer, randomId, option });
|
||||
const result = await callApi('reportSponsoredMessage', { randomId, option });
|
||||
|
||||
if (!result) return;
|
||||
|
||||
@ -2352,6 +2358,8 @@ addActionHandler('scheduleForViewsIncrement', (global, actions, payload): Action
|
||||
addActionHandler('loadMessageViews', async (global, actions, payload): Promise<void> => {
|
||||
const { chatId, ids, shouldIncrement } = payload;
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const chat = selectChat(global, chatId);
|
||||
if (!chat) return;
|
||||
|
||||
|
||||
@ -40,6 +40,7 @@ import { updateTabState } from '../../reducers/tabs';
|
||||
import {
|
||||
selectChat,
|
||||
selectChatFullInfo,
|
||||
selectIsCurrentUserFrozen,
|
||||
selectPaymentInputInvoice,
|
||||
selectPaymentRequestId,
|
||||
selectProviderPublicToken,
|
||||
@ -530,6 +531,11 @@ addActionHandler('openGiftModal', async (global, actions, payload): Promise<void
|
||||
forUserId, tabId = getCurrentTabId(),
|
||||
} = payload;
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
actions.openFrozenAccountModal({ tabId });
|
||||
return;
|
||||
}
|
||||
|
||||
const gifts = await callApi('getPremiumGiftCodeOptions', {});
|
||||
if (!gifts) return;
|
||||
|
||||
@ -549,6 +555,11 @@ addActionHandler('openStarsGiftModal', async (global, actions, payload): Promise
|
||||
tabId = getCurrentTabId(),
|
||||
} = payload || {};
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
actions.openFrozenAccountModal({ tabId });
|
||||
return;
|
||||
}
|
||||
|
||||
const starsGiftOptions = await callApi('getStarsGiftOptions', {});
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
@ -31,6 +31,7 @@ import {
|
||||
selectCurrentChat,
|
||||
selectDefaultReaction,
|
||||
selectIsChatWithSelf,
|
||||
selectIsCurrentUserFrozen,
|
||||
selectMaxUserReactions,
|
||||
selectMessageIdsByGroupId,
|
||||
selectPerformanceSettingsValue,
|
||||
@ -391,6 +392,8 @@ addActionHandler('stopActiveEmojiInteraction', (global, actions, payload): Actio
|
||||
});
|
||||
|
||||
addActionHandler('loadReactors', async (global, actions, payload): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const { chatId, messageId, reaction } = payload;
|
||||
const chat = selectChat(global, chatId);
|
||||
const message = selectChatMessage(global, chatId, messageId);
|
||||
@ -418,6 +421,8 @@ addActionHandler('loadReactors', async (global, actions, payload): Promise<void>
|
||||
});
|
||||
|
||||
addActionHandler('loadMessageReactions', (global, actions, payload): ActionReturnType => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const { ids, chatId } = payload;
|
||||
|
||||
const chat = selectChat(global, chatId);
|
||||
|
||||
@ -22,7 +22,8 @@ import {
|
||||
} from '../../reducers';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
import {
|
||||
selectChat, selectTabState, selectUser,
|
||||
selectChat, selectIsCurrentUserFrozen,
|
||||
selectTabState, selectUser,
|
||||
} from '../../selectors';
|
||||
import { selectSharedSettings } from '../../selectors/sharedState';
|
||||
|
||||
@ -390,6 +391,8 @@ addActionHandler('loadLanguages', async (global): Promise<void> => {
|
||||
});
|
||||
|
||||
addActionHandler('loadPrivacySettings', async (global): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const result = await Promise.all([
|
||||
callApi('fetchPrivacySettings', 'phoneNumber'),
|
||||
callApi('fetchPrivacySettings', 'addByPhone'),
|
||||
@ -574,6 +577,8 @@ addActionHandler('updateIsOnline', (global, actions, payload): ActionReturnType
|
||||
});
|
||||
|
||||
addActionHandler('loadContentSettings', async (global): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const result = await callApi('fetchContentSettings');
|
||||
if (!result) return;
|
||||
|
||||
@ -644,6 +649,7 @@ addActionHandler('loadAppConfig', async (global, actions, payload): Promise<void
|
||||
global = {
|
||||
...global,
|
||||
appConfig,
|
||||
isAppConfigLoaded: true,
|
||||
};
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
@ -27,6 +27,7 @@ import {
|
||||
} from '../../reducers';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
import {
|
||||
selectIsCurrentUserFrozen,
|
||||
selectPeer, selectPeerStories, selectPeerStory,
|
||||
selectPinnedStories, selectTabState,
|
||||
} from '../../selectors';
|
||||
@ -278,6 +279,8 @@ addActionHandler('toggleStoryPinnedToTop', async (global, actions, payload): Pro
|
||||
});
|
||||
|
||||
addActionHandler('loadPeerStories', async (global, actions, payload): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const { peerId } = payload;
|
||||
const peer = selectPeer(global, peerId);
|
||||
if (!peer) return;
|
||||
@ -296,6 +299,8 @@ addActionHandler('loadPeerStories', async (global, actions, payload): Promise<vo
|
||||
});
|
||||
|
||||
addActionHandler('loadPeerProfileStories', async (global, actions, payload): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const { peerId, offsetId } = payload;
|
||||
const peer = selectPeer(global, peerId);
|
||||
let peerStories = selectPeerStories(global, peerId);
|
||||
@ -320,6 +325,8 @@ addActionHandler('loadPeerProfileStories', async (global, actions, payload): Pro
|
||||
});
|
||||
|
||||
addActionHandler('loadStoriesArchive', async (global, actions, payload): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const { peerId, offsetId } = payload;
|
||||
const peer = selectPeer(global, peerId);
|
||||
let peerStories = selectPeerStories(global, peerId);
|
||||
|
||||
@ -29,7 +29,9 @@ import {
|
||||
updateStickersForEmoji,
|
||||
} from '../../reducers';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
import { selectIsCurrentUserPremium, selectStickerSet, selectTabState } from '../../selectors';
|
||||
import {
|
||||
selectIsCurrentUserFrozen, selectIsCurrentUserPremium, selectStickerSet, selectTabState,
|
||||
} from '../../selectors';
|
||||
import { selectCurrentLimit, selectPremiumLimit } from '../../selectors/limits';
|
||||
|
||||
const ADDED_SETS_THROTTLE = 200;
|
||||
@ -128,6 +130,10 @@ addActionHandler('loadFavoriteStickers', async (global): Promise<void> => {
|
||||
addActionHandler('loadPremiumStickers', async (global): Promise<void> => {
|
||||
const { hash } = global.stickers.premium || {};
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await callApi('fetchStickersForEmoji', { emoji: '⭐️⭐️', hash });
|
||||
if (!result) {
|
||||
return;
|
||||
@ -151,6 +157,10 @@ addActionHandler('loadPremiumStickers', async (global): Promise<void> => {
|
||||
addActionHandler('loadGreetingStickers', async (global): Promise<void> => {
|
||||
const { hash } = global.stickers.greeting || {};
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const greeting = await callApi('fetchStickersForEmoji', { emoji: '👋⭐️', hash });
|
||||
if (!greeting) {
|
||||
return;
|
||||
|
||||
@ -66,7 +66,7 @@ addActionHandler('sync', (global, actions): ActionReturnType => {
|
||||
}, RELEASE_STATUS_TIMEOUT);
|
||||
|
||||
const {
|
||||
loadAllChats, preloadTopChatMessages, loadAllStories, loadAllHiddenStories,
|
||||
loadAllChats, preloadTopChatMessages,
|
||||
} = actions;
|
||||
|
||||
initFolderManager();
|
||||
@ -91,10 +91,7 @@ addActionHandler('sync', (global, actions): ActionReturnType => {
|
||||
}
|
||||
|
||||
loadAllChats({ listType: 'archived' });
|
||||
loadAllChats({ listType: 'saved' });
|
||||
preloadTopChatMessages();
|
||||
loadAllStories();
|
||||
loadAllHiddenStories();
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@ -30,6 +30,7 @@ import { updateTabState } from '../../reducers/tabs';
|
||||
import {
|
||||
selectChat,
|
||||
selectChatFullInfo,
|
||||
selectIsCurrentUserFrozen,
|
||||
selectIsCurrentUserPremium,
|
||||
selectPeer,
|
||||
selectPeerPhotos,
|
||||
@ -159,6 +160,11 @@ addActionHandler('loadCurrentUser', (): ActionReturnType => {
|
||||
|
||||
addActionHandler('loadCommonChats', async (global, actions, payload): Promise<void> => {
|
||||
const { userId } = payload;
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const user = selectUser(global, userId);
|
||||
const commonChats = selectUserCommonChats(global, userId);
|
||||
if (!user || isUserBot(user) || commonChats?.isFullyLoaded) {
|
||||
@ -294,6 +300,8 @@ addActionHandler('deleteContact', async (global, actions, payload): Promise<void
|
||||
});
|
||||
|
||||
addActionHandler('loadMoreProfilePhotos', async (global, actions, payload): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const { peerId, shouldInvalidateCache, isPreload } = payload;
|
||||
const isPrivate = isUserId(peerId);
|
||||
|
||||
@ -550,6 +558,8 @@ addActionHandler('openSuggestedStatusModal', async (global, actions, payload): P
|
||||
addActionHandler('loadPeerSettings', async (global, actions, payload): Promise<void> => {
|
||||
const { peerId } = payload;
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const userFullInfo = selectUserFullInfo(global, peerId);
|
||||
if (!userFullInfo) {
|
||||
actions.loadFullUser({ userId: peerId });
|
||||
|
||||
@ -95,6 +95,19 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'notSupportedInFrozenAccount': {
|
||||
actions.showNotification({
|
||||
title: {
|
||||
key: 'NotificationTitleNotSupportedInFrozenAccount',
|
||||
},
|
||||
message: {
|
||||
key: 'NotificationMessageNotSupportedInFrozenAccount',
|
||||
},
|
||||
tabId: getCurrentTabId(),
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
21
src/global/actions/ui/account.ts
Normal file
21
src/global/actions/ui/account.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import type { ActionReturnType } from '../../types';
|
||||
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { addActionHandler } from '../..';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
|
||||
addActionHandler('openFrozenAccountModal', (global, actions, payload): ActionReturnType => {
|
||||
const { tabId = getCurrentTabId() } = payload || {};
|
||||
|
||||
return updateTabState(global, {
|
||||
isFrozenAccountModalOpen: true,
|
||||
}, tabId);
|
||||
});
|
||||
|
||||
addActionHandler('closeFrozenAccountModal', (global, actions, payload): ActionReturnType => {
|
||||
const { tabId = getCurrentTabId() } = payload || {};
|
||||
|
||||
return updateTabState(global, {
|
||||
isFrozenAccountModalOpen: false,
|
||||
}, tabId);
|
||||
});
|
||||
@ -21,7 +21,8 @@ import {
|
||||
import { updateGroupCall } from '../../reducers/calls';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
import {
|
||||
selectChat, selectChatFullInfo, selectTabState, selectUser,
|
||||
selectChat, selectChatFullInfo, selectIsCurrentUserFrozen,
|
||||
selectTabState, selectUser,
|
||||
} from '../../selectors';
|
||||
import { selectActiveGroupCall, selectChatGroupCall, selectGroupCall } from '../../selectors/calls';
|
||||
import { fetchChatByUsername, loadFullChat } from '../api/chats';
|
||||
@ -90,6 +91,7 @@ export function initializeSounds() {
|
||||
}
|
||||
|
||||
async function fetchGroupCall<T extends GlobalState>(global: T, groupCall: Partial<ApiGroupCall>) {
|
||||
if (selectIsCurrentUserFrozen(global)) return undefined;
|
||||
const result = await callApi('getGroupCall', {
|
||||
call: groupCall,
|
||||
});
|
||||
@ -130,6 +132,8 @@ addActionHandler('toggleGroupCallPanel', (global, actions, payload): ActionRetur
|
||||
});
|
||||
|
||||
addActionHandler('subscribeToGroupCallUpdates', async (global, actions, payload): Promise<void> => {
|
||||
if (selectIsCurrentUserFrozen(global)) return;
|
||||
|
||||
const { subscribed, id } = payload!;
|
||||
const groupCall = selectGroupCall(global, id);
|
||||
|
||||
|
||||
@ -10,7 +10,9 @@ import {
|
||||
clearStarPayment, openStarsTransactionModal,
|
||||
} from '../../reducers';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
import { selectChatMessage, selectStarsPayment, selectTabState } from '../../selectors';
|
||||
import {
|
||||
selectChatMessage, selectIsCurrentUserFrozen, selectStarsPayment, selectTabState,
|
||||
} from '../../selectors';
|
||||
|
||||
addActionHandler('processOriginStarsPayment', (global, actions, payload): ActionReturnType => {
|
||||
const { originData, status, tabId = getCurrentTabId() } = payload;
|
||||
@ -59,6 +61,11 @@ addActionHandler('openGiftRecipientPicker', (global, actions, payload): ActionRe
|
||||
tabId = getCurrentTabId(),
|
||||
} = payload || {};
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
actions.openFrozenAccountModal({ tabId });
|
||||
return global;
|
||||
}
|
||||
|
||||
return updateTabState(global, {
|
||||
isGiftRecipientPickerOpen: true,
|
||||
}, tabId);
|
||||
|
||||
@ -5,6 +5,7 @@ import { addTabStateResetterAction } from '../../helpers/meta';
|
||||
import { addActionHandler } from '../../index';
|
||||
import { closeNewContactDialog, updateUserSearch } from '../../reducers';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
import { selectIsCurrentUserFrozen } from '../../selectors';
|
||||
|
||||
addActionHandler('setUserSearchQuery', (global, actions, payload): ActionReturnType => {
|
||||
const {
|
||||
@ -23,6 +24,11 @@ addActionHandler('setUserSearchQuery', (global, actions, payload): ActionReturnT
|
||||
addActionHandler('openAddContactDialog', (global, actions, payload): ActionReturnType => {
|
||||
const { userId, tabId = getCurrentTabId() } = payload;
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
actions.openFrozenAccountModal({ tabId });
|
||||
return global;
|
||||
}
|
||||
|
||||
return updateTabState(global, {
|
||||
newContact: { userId },
|
||||
}, tabId);
|
||||
@ -31,6 +37,11 @@ addActionHandler('openAddContactDialog', (global, actions, payload): ActionRetur
|
||||
addActionHandler('openNewContactDialog', (global, actions, payload): ActionReturnType => {
|
||||
const { tabId = getCurrentTabId() } = payload || {};
|
||||
|
||||
if (selectIsCurrentUserFrozen(global)) {
|
||||
actions.openFrozenAccountModal({ tabId });
|
||||
return global;
|
||||
}
|
||||
|
||||
return updateTabState(global, {
|
||||
newContact: {
|
||||
isByPhoneNumber: true,
|
||||
|
||||
@ -35,6 +35,10 @@ export function selectIsCurrentUserPremium<T extends GlobalState>(global: T) {
|
||||
return Boolean(global.users.byId[global.currentUserId].isPremium);
|
||||
}
|
||||
|
||||
export function selectIsCurrentUserFrozen<T extends GlobalState>(global: T) {
|
||||
return Boolean(global.appConfig?.freezeUntilDate);
|
||||
}
|
||||
|
||||
export function selectIsPremiumPurchaseBlocked<T extends GlobalState>(global: T) {
|
||||
return global.appConfig?.isPremiumPurchaseBlocked ?? true;
|
||||
}
|
||||
|
||||
@ -1026,6 +1026,8 @@ export interface ActionPayloads {
|
||||
changeSessionTtl: {
|
||||
days: number;
|
||||
};
|
||||
openFrozenAccountModal: WithTabId | undefined;
|
||||
closeFrozenAccountModal: WithTabId | undefined;
|
||||
|
||||
// Chats
|
||||
loadPeerSettings: {
|
||||
@ -1713,6 +1715,7 @@ export interface ActionPayloads {
|
||||
startBotFatherConversation: {
|
||||
param: string;
|
||||
} & WithTabId;
|
||||
loadBotFreezeAppeal: undefined;
|
||||
checkUsername: {
|
||||
username: string;
|
||||
} & WithTabId;
|
||||
|
||||
@ -84,6 +84,7 @@ export type GlobalState = {
|
||||
connectionState?: ApiUpdateConnectionStateType;
|
||||
currentUserId?: string;
|
||||
isSyncing?: boolean;
|
||||
isAppConfigLoaded?: boolean;
|
||||
isAppUpdateAvailable?: boolean;
|
||||
isElectronUpdateAvailable?: boolean;
|
||||
isSynced?: boolean;
|
||||
@ -92,6 +93,7 @@ export type GlobalState = {
|
||||
lastIsChatInfoShown?: boolean;
|
||||
initialUnreadNotifications?: number;
|
||||
shouldShowContextMenuHint?: boolean;
|
||||
botFreezeAppealId?: string;
|
||||
|
||||
audioPlayer: {
|
||||
lastPlaybackRate: number;
|
||||
|
||||
@ -618,6 +618,8 @@ export type TabState = {
|
||||
|
||||
isGiftRecipientPickerOpen?: boolean;
|
||||
|
||||
isFrozenAccountModalOpen?: boolean;
|
||||
|
||||
starsGiftingPickerModal?: {
|
||||
isOpen?: boolean;
|
||||
};
|
||||
|
||||
@ -12,5 +12,5 @@ for (const tl of Object.values(Api)) {
|
||||
}
|
||||
}
|
||||
|
||||
export const LAYER = 200;
|
||||
export const LAYER = 201;
|
||||
export { tlobjects };
|
||||
|
||||
194
src/lib/gramjs/tl/api.d.ts
vendored
194
src/lib/gramjs/tl/api.d.ts
vendored
File diff suppressed because one or more lines are too long
@ -159,6 +159,8 @@ messageActionGiftStars#45d5b021 flags:# currency:string amount:long stars:long c
|
||||
messageActionPrizeStars#b00c47a2 flags:# unclaimed:flags.0?true stars:long transaction_id:string boost_peer:Peer giveaway_msg_id:int = MessageAction;
|
||||
messageActionStarGift#4717e8a4 flags:# name_hidden:flags.0?true saved:flags.2?true converted:flags.3?true upgraded:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true gift:StarGift message:flags.1?TextWithEntities convert_stars:flags.4?long upgrade_msg_id:flags.5?int upgrade_stars:flags.8?long from_id:flags.11?Peer peer:flags.12?Peer saved_id:flags.12?long = MessageAction;
|
||||
messageActionStarGiftUnique#acdfcb81 flags:# upgrade:flags.0?true transferred:flags.1?true saved:flags.2?true refunded:flags.5?true gift:StarGift can_export_at:flags.3?int transfer_stars:flags.4?long from_id:flags.6?Peer peer:flags.7?Peer saved_id:flags.7?long = MessageAction;
|
||||
messageActionPaidMessagesRefunded#ac1f1fcd count:int stars:long = MessageAction;
|
||||
messageActionPaidMessagesPrice#bcd71419 stars:long = MessageAction;
|
||||
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
|
||||
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
||||
photoEmpty#2331b22d id:long = Photo;
|
||||
@ -173,6 +175,7 @@ geoPointEmpty#1117dd5f = GeoPoint;
|
||||
geoPoint#b2a2f663 flags:# long:double lat:double access_hash:long accuracy_radius:flags.0?int = GeoPoint;
|
||||
auth.sentCode#5e002502 flags:# type:auth.SentCodeType phone_code_hash:string next_type:flags.1?auth.CodeType timeout:flags.2?int = auth.SentCode;
|
||||
auth.sentCodeSuccess#2390fe44 authorization:auth.Authorization = auth.SentCode;
|
||||
auth.sentCodePaymentRequired#d7cef980 store_product:string phone_code_hash:string = auth.SentCode;
|
||||
auth.authorization#2ea2c0d4 flags:# setup_password_required:flags.1?true otherwise_relogin_days:flags.1?int tmp_sessions:flags.0?int future_auth_token:flags.2?bytes user:User = auth.Authorization;
|
||||
auth.authorizationSignUpRequired#44747e9a flags:# terms_of_service:flags.0?help.TermsOfService = auth.Authorization;
|
||||
auth.exportedAuthorization#b434e2b8 id:long bytes:bytes = auth.ExportedAuthorization;
|
||||
@ -196,7 +199,7 @@ inputReportReasonGeoIrrelevant#dbd4feed = ReportReason;
|
||||
inputReportReasonFake#f5ddd6e7 = ReportReason;
|
||||
inputReportReasonIllegalDrugs#a8eb2be = ReportReason;
|
||||
inputReportReasonPersonalDetails#9ec7863d = ReportReason;
|
||||
userFull#d2234ea0 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# sponsored_enabled:flags2.7?true can_view_revenue:flags2.9?true bot_can_manage_emoji_status:flags2.10?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int stargifts_count:flags2.8?int starref_program:flags2.11?StarRefProgram bot_verification:flags2.12?BotVerification send_paid_messages_stars:flags2.14?long = UserFull;
|
||||
userFull#99e78045 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# sponsored_enabled:flags2.7?true can_view_revenue:flags2.9?true bot_can_manage_emoji_status:flags2.10?true display_gifts_button:flags2.16?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int stargifts_count:flags2.8?int starref_program:flags2.11?StarRefProgram bot_verification:flags2.12?BotVerification send_paid_messages_stars:flags2.14?long disallowed_gifts:flags2.15?DisallowedGiftsSettings = UserFull;
|
||||
contact#145ade0b user_id:long mutual:Bool = Contact;
|
||||
importedContact#c13e3c50 user_id:long client_id:long = ImportedContact;
|
||||
contactStatus#16d9703b user_id:long status:UserStatus = ContactStatus;
|
||||
@ -374,6 +377,7 @@ updateBusinessBotCallbackQuery#1ea2fda7 flags:# query_id:long user_id:long conne
|
||||
updateStarsRevenueStatus#a584b019 peer:Peer status:StarsRevenueStatus = Update;
|
||||
updateBotPurchasedPaidMedia#283bd312 user_id:long payload:string qts:int = Update;
|
||||
updatePaidReactionPrivacy#8b725fce private:PaidReactionPrivacy = Update;
|
||||
updateSentPhoneCode#504aa18f sent_code:auth.SentCode = Update;
|
||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||
updates.differenceEmpty#5d75a138 date:int seq:int = updates.Difference;
|
||||
updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> state:updates.State = updates.Difference;
|
||||
@ -746,7 +750,6 @@ phoneCallDiscardReasonMissed#85e42301 = PhoneCallDiscardReason;
|
||||
phoneCallDiscardReasonDisconnect#e095c1a0 = PhoneCallDiscardReason;
|
||||
phoneCallDiscardReasonHangup#57adc690 = PhoneCallDiscardReason;
|
||||
phoneCallDiscardReasonBusy#faf7e8c9 = PhoneCallDiscardReason;
|
||||
phoneCallDiscardReasonAllowGroupCall#afe2b839 encrypted_key:bytes = PhoneCallDiscardReason;
|
||||
dataJSON#7d748d04 data:string = DataJSON;
|
||||
labeledPrice#cb296bf8 label:string amount:long = LabeledPrice;
|
||||
invoice#49ee584 flags:# test:flags.0?true name_requested:flags.1?true phone_requested:flags.2?true email_requested:flags.3?true shipping_address_requested:flags.4?true flexible:flags.5?true phone_to_provider:flags.6?true email_to_provider:flags.7?true recurring:flags.9?true currency:string prices:Vector<LabeledPrice> max_tip_amount:flags.8?long suggested_tip_amounts:flags.8?Vector<long> terms_url:flags.10?string subscription_period:flags.11?int = Invoice;
|
||||
@ -1025,7 +1028,7 @@ statsGroupTopPoster#9d04af9b user_id:long messages:int avg_chars:int = StatsGrou
|
||||
statsGroupTopAdmin#d7584c87 user_id:long deleted:int kicked:int banned:int = StatsGroupTopAdmin;
|
||||
statsGroupTopInviter#535f779d user_id:long invitations:int = StatsGroupTopInviter;
|
||||
stats.megagroupStats#ef7ff916 period:StatsDateRangeDays members:StatsAbsValueAndPrev messages:StatsAbsValueAndPrev viewers:StatsAbsValueAndPrev posters:StatsAbsValueAndPrev growth_graph:StatsGraph members_graph:StatsGraph new_members_by_source_graph:StatsGraph languages_graph:StatsGraph messages_graph:StatsGraph actions_graph:StatsGraph top_hours_graph:StatsGraph weekdays_graph:StatsGraph top_posters:Vector<StatsGroupTopPoster> top_admins:Vector<StatsGroupTopAdmin> top_inviters:Vector<StatsGroupTopInviter> users:Vector<User> = stats.MegagroupStats;
|
||||
globalPrivacySettings#c9d8df1c flags:# archive_and_mute_new_noncontact_peers:flags.0?true keep_archived_unmuted:flags.1?true keep_archived_folders:flags.2?true hide_read_marks:flags.3?true new_noncontact_peers_require_premium:flags.4?true noncontact_peers_paid_stars:flags.5?long = GlobalPrivacySettings;
|
||||
globalPrivacySettings#fe41b34f flags:# archive_and_mute_new_noncontact_peers:flags.0?true keep_archived_unmuted:flags.1?true keep_archived_folders:flags.2?true hide_read_marks:flags.3?true new_noncontact_peers_require_premium:flags.4?true display_gifts_button:flags.7?true noncontact_peers_paid_stars:flags.5?long disallowed_gifts:flags.6?DisallowedGiftsSettings = GlobalPrivacySettings;
|
||||
help.countryCode#4203c5ef flags:# country_code:string prefixes:flags.0?Vector<string> patterns:flags.1?Vector<string> = help.CountryCode;
|
||||
help.country#c3878e23 flags:# hidden:flags.0?true iso2:string default_name:string name:flags.1?string country_codes:Vector<help.CountryCode> = help.Country;
|
||||
help.countriesListNotModified#93cc1f32 = help.CountriesList;
|
||||
@ -1130,6 +1133,7 @@ inputInvoiceStarGift#e8625e92 flags:# hide_name:flags.0?true include_upgrade:fla
|
||||
inputInvoiceStarGiftUpgrade#4d818d5d flags:# keep_original_details:flags.0?true stargift:InputSavedStarGift = InputInvoice;
|
||||
inputInvoiceStarGiftTransfer#4a5f5bd9 stargift:InputSavedStarGift to_id:InputPeer = InputInvoice;
|
||||
inputInvoicePremiumGiftStars#dabab2ef flags:# user_id:InputUser months:int message:flags.0?TextWithEntities = InputInvoice;
|
||||
inputInvoiceBusinessBotTransferStars#f4997e42 bot:InputUser stars:long = InputInvoice;
|
||||
payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice;
|
||||
messages.transcribedAudio#cfb9d957 flags:# pending:flags.0?true transcription_id:long text:string trial_remains_num:flags.1?int trial_remains_until_date:flags.1?int = messages.TranscribedAudio;
|
||||
help.premiumPromo#5334759c status_text:string status_entities:Vector<MessageEntity> video_sections:Vector<string> videos:Vector<Document> period_options:Vector<PremiumSubscriptionOption> users:Vector<User> = help.PremiumPromo;
|
||||
@ -1140,6 +1144,7 @@ inputStorePaymentPremiumGiveaway#160544ca flags:# only_new_subscribers:flags.0?t
|
||||
inputStorePaymentStarsTopup#dddd0f56 stars:long currency:string amount:long = InputStorePaymentPurpose;
|
||||
inputStorePaymentStarsGift#1d741ef7 user_id:InputUser stars:long currency:string amount:long = InputStorePaymentPurpose;
|
||||
inputStorePaymentStarsGiveaway#751f08fa flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.3?true stars:long boost_peer:InputPeer additional_peers:flags.1?Vector<InputPeer> countries_iso2:flags.2?Vector<string> prize_description:flags.4?string random_id:long until_date:int currency:string amount:long users:int = InputStorePaymentPurpose;
|
||||
inputStorePaymentAuthCode#9bb2636d flags:# restore:flags.0?true phone_number:string phone_code_hash:string currency:string amount:long = InputStorePaymentPurpose;
|
||||
paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod;
|
||||
emojiStatusEmpty#2de11aae = EmojiStatus;
|
||||
emojiStatus#e7ff068a flags:# document_id:long until:flags.0?int = EmojiStatus;
|
||||
@ -1298,11 +1303,11 @@ inputQuickReplyShortcut#24596d41 shortcut:string = InputQuickReplyShortcut;
|
||||
inputQuickReplyShortcutId#1190cf1 shortcut_id:int = InputQuickReplyShortcut;
|
||||
messages.quickReplies#c68d6695 quick_replies:Vector<QuickReply> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.QuickReplies;
|
||||
messages.quickRepliesNotModified#5f91eb5b = messages.QuickReplies;
|
||||
connectedBot#bd068601 flags:# can_reply:flags.0?true bot_id:long recipients:BusinessBotRecipients = ConnectedBot;
|
||||
connectedBot#cd64636c flags:# bot_id:long recipients:BusinessBotRecipients rights:BusinessBotRights = ConnectedBot;
|
||||
account.connectedBots#17d7f87b connected_bots:Vector<ConnectedBot> users:Vector<User> = account.ConnectedBots;
|
||||
messages.dialogFilters#2ad93719 flags:# tags_enabled:flags.0?true filters:Vector<DialogFilter> = messages.DialogFilters;
|
||||
birthday#6c8e1e06 flags:# day:int month:int year:flags.0?int = Birthday;
|
||||
botBusinessConnection#896433b4 flags:# can_reply:flags.0?true disabled:flags.1?true connection_id:string user_id:long dc_id:int date:int = BotBusinessConnection;
|
||||
botBusinessConnection#8f34b2f5 flags:# disabled:flags.1?true connection_id:string user_id:long dc_id:int date:int rights:flags.2?BusinessBotRights = BotBusinessConnection;
|
||||
inputBusinessIntro#9c469cd flags:# title:string description:string sticker:flags.0?InputDocument = InputBusinessIntro;
|
||||
businessIntro#5a0a066d flags:# title:string description:string sticker:flags.0?Document = BusinessIntro;
|
||||
messages.myStickers#faff629d count:int sets:Vector<StickerSetCovered> = messages.MyStickers;
|
||||
@ -1409,6 +1414,11 @@ account.paidMessagesRevenue#1e109708 stars_amount:long = account.PaidMessagesRev
|
||||
requirementToContactEmpty#50a9839 = RequirementToContact;
|
||||
requirementToContactPremium#e581e4e9 = RequirementToContact;
|
||||
requirementToContactPaidMessages#b4f67e93 stars_amount:long = RequirementToContact;
|
||||
businessBotRights#a0624cf7 flags:# reply:flags.0?true read_messages:flags.1?true delete_sent_messages:flags.2?true delete_received_messages:flags.3?true edit_name:flags.4?true edit_bio:flags.5?true edit_profile_photo:flags.6?true edit_username:flags.7?true view_gifts:flags.8?true sell_gifts:flags.9?true change_gift_settings:flags.10?true transfer_and_upgrade_gifts:flags.11?true transfer_stars:flags.12?true manage_stories:flags.13?true = BusinessBotRights;
|
||||
disallowedGiftsSettings#71f276c4 flags:# disallow_unlimited_stargifts:flags.0?true disallow_limited_stargifts:flags.1?true disallow_unique_stargifts:flags.2?true disallow_premium_gifts:flags.3?true = DisallowedGiftsSettings;
|
||||
sponsoredPeer#c69708d3 flags:# random_id:bytes peer:Peer sponsor_info:flags.0?string additional_info:flags.1?string = SponsoredPeer;
|
||||
contacts.sponsoredPeersEmpty#ea32b4b1 = contacts.SponsoredPeers;
|
||||
contacts.sponsoredPeers#eb032884 peers:Vector<SponsoredPeer> chats:Vector<Chat> users:Vector<User> = contacts.SponsoredPeers;
|
||||
---functions---
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
initConnection#c1cd5ea9 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy params:flags.1?JSONValue query:!X = X;
|
||||
@ -1476,7 +1486,6 @@ account.addNoPaidMessagesException#6f688aa7 flags:# refund_charged:flags.0?true
|
||||
account.getPaidMessagesRevenue#f1266f38 user_id:InputUser = account.PaidMessagesRevenue;
|
||||
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
||||
users.getFullUser#b60f5918 id:InputUser = users.UserFull;
|
||||
users.getRequirementsToContact#d89a83a3 id:Vector<InputUser> = Vector<RequirementToContact>;
|
||||
contacts.getContacts#5dd69e12 hash:long = contacts.Contacts;
|
||||
contacts.importContacts#2c800be5 contacts:Vector<InputContact> = contacts.ImportedContacts;
|
||||
contacts.deleteContacts#96a0e00 id:Vector<InputUser> = Updates;
|
||||
@ -1629,9 +1638,9 @@ messages.getFactCheck#b9cdc5ee peer:InputPeer msg_id:Vector<int> = Vector<FactCh
|
||||
messages.requestMainWebView#c9e01e7b flags:# compact:flags.7?true fullscreen:flags.8?true peer:InputPeer bot:InputUser start_param:flags.1?string theme_params:flags.0?DataJSON platform:string = WebViewResult;
|
||||
messages.sendPaidReaction#58bbcb50 flags:# peer:InputPeer msg_id:int count:int random_id:long private:flags.0?PaidReactionPrivacy = Updates;
|
||||
messages.getPaidReactionPrivacy#472455aa = Updates;
|
||||
messages.viewSponsoredMessage#673ad8f1 peer:InputPeer random_id:bytes = Bool;
|
||||
messages.clickSponsoredMessage#f093465 flags:# media:flags.0?true fullscreen:flags.1?true peer:InputPeer random_id:bytes = Bool;
|
||||
messages.reportSponsoredMessage#1af3dbb8 peer:InputPeer random_id:bytes option:bytes = channels.SponsoredMessageReportResult;
|
||||
messages.viewSponsoredMessage#269e3643 random_id:bytes = Bool;
|
||||
messages.clickSponsoredMessage#8235057e flags:# media:flags.0?true fullscreen:flags.1?true random_id:bytes = Bool;
|
||||
messages.reportSponsoredMessage#12cbf0c4 random_id:bytes option:bytes = channels.SponsoredMessageReportResult;
|
||||
messages.getSponsoredMessages#9bd2f439 peer:InputPeer = messages.SponsoredMessages;
|
||||
messages.getPreparedInlineMessage#857ebdb8 bot:InputUser id:string = messages.PreparedInlineMessage;
|
||||
messages.reportMessagesDelivery#5a6d7395 flags:# push:flags.0?true peer:InputPeer id:Vector<int> = Bool;
|
||||
|
||||
@ -185,6 +185,8 @@ messageActionGiftStars#45d5b021 flags:# currency:string amount:long stars:long c
|
||||
messageActionPrizeStars#b00c47a2 flags:# unclaimed:flags.0?true stars:long transaction_id:string boost_peer:Peer giveaway_msg_id:int = MessageAction;
|
||||
messageActionStarGift#4717e8a4 flags:# name_hidden:flags.0?true saved:flags.2?true converted:flags.3?true upgraded:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true gift:StarGift message:flags.1?TextWithEntities convert_stars:flags.4?long upgrade_msg_id:flags.5?int upgrade_stars:flags.8?long from_id:flags.11?Peer peer:flags.12?Peer saved_id:flags.12?long = MessageAction;
|
||||
messageActionStarGiftUnique#acdfcb81 flags:# upgrade:flags.0?true transferred:flags.1?true saved:flags.2?true refunded:flags.5?true gift:StarGift can_export_at:flags.3?int transfer_stars:flags.4?long from_id:flags.6?Peer peer:flags.7?Peer saved_id:flags.7?long = MessageAction;
|
||||
messageActionPaidMessagesRefunded#ac1f1fcd count:int stars:long = MessageAction;
|
||||
messageActionPaidMessagesPrice#bcd71419 stars:long = MessageAction;
|
||||
|
||||
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
|
||||
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
||||
@ -204,6 +206,7 @@ geoPoint#b2a2f663 flags:# long:double lat:double access_hash:long accuracy_radiu
|
||||
|
||||
auth.sentCode#5e002502 flags:# type:auth.SentCodeType phone_code_hash:string next_type:flags.1?auth.CodeType timeout:flags.2?int = auth.SentCode;
|
||||
auth.sentCodeSuccess#2390fe44 authorization:auth.Authorization = auth.SentCode;
|
||||
auth.sentCodePaymentRequired#d7cef980 store_product:string phone_code_hash:string = auth.SentCode;
|
||||
|
||||
auth.authorization#2ea2c0d4 flags:# setup_password_required:flags.1?true otherwise_relogin_days:flags.1?int tmp_sessions:flags.0?int future_auth_token:flags.2?bytes user:User = auth.Authorization;
|
||||
auth.authorizationSignUpRequired#44747e9a flags:# terms_of_service:flags.0?help.TermsOfService = auth.Authorization;
|
||||
@ -236,7 +239,7 @@ inputReportReasonFake#f5ddd6e7 = ReportReason;
|
||||
inputReportReasonIllegalDrugs#a8eb2be = ReportReason;
|
||||
inputReportReasonPersonalDetails#9ec7863d = ReportReason;
|
||||
|
||||
userFull#d2234ea0 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# sponsored_enabled:flags2.7?true can_view_revenue:flags2.9?true bot_can_manage_emoji_status:flags2.10?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int stargifts_count:flags2.8?int starref_program:flags2.11?StarRefProgram bot_verification:flags2.12?BotVerification send_paid_messages_stars:flags2.14?long = UserFull;
|
||||
userFull#99e78045 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# sponsored_enabled:flags2.7?true can_view_revenue:flags2.9?true bot_can_manage_emoji_status:flags2.10?true display_gifts_button:flags2.16?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int stargifts_count:flags2.8?int starref_program:flags2.11?StarRefProgram bot_verification:flags2.12?BotVerification send_paid_messages_stars:flags2.14?long disallowed_gifts:flags2.15?DisallowedGiftsSettings = UserFull;
|
||||
|
||||
contact#145ade0b user_id:long mutual:Bool = Contact;
|
||||
|
||||
@ -427,6 +430,7 @@ updateBusinessBotCallbackQuery#1ea2fda7 flags:# query_id:long user_id:long conne
|
||||
updateStarsRevenueStatus#a584b019 peer:Peer status:StarsRevenueStatus = Update;
|
||||
updateBotPurchasedPaidMedia#283bd312 user_id:long payload:string qts:int = Update;
|
||||
updatePaidReactionPrivacy#8b725fce private:PaidReactionPrivacy = Update;
|
||||
updateSentPhoneCode#504aa18f sent_code:auth.SentCode = Update;
|
||||
|
||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||
|
||||
@ -897,7 +901,6 @@ phoneCallDiscardReasonMissed#85e42301 = PhoneCallDiscardReason;
|
||||
phoneCallDiscardReasonDisconnect#e095c1a0 = PhoneCallDiscardReason;
|
||||
phoneCallDiscardReasonHangup#57adc690 = PhoneCallDiscardReason;
|
||||
phoneCallDiscardReasonBusy#faf7e8c9 = PhoneCallDiscardReason;
|
||||
phoneCallDiscardReasonAllowGroupCall#afe2b839 encrypted_key:bytes = PhoneCallDiscardReason;
|
||||
|
||||
dataJSON#7d748d04 data:string = DataJSON;
|
||||
|
||||
@ -1311,7 +1314,7 @@ statsGroupTopInviter#535f779d user_id:long invitations:int = StatsGroupTopInvite
|
||||
|
||||
stats.megagroupStats#ef7ff916 period:StatsDateRangeDays members:StatsAbsValueAndPrev messages:StatsAbsValueAndPrev viewers:StatsAbsValueAndPrev posters:StatsAbsValueAndPrev growth_graph:StatsGraph members_graph:StatsGraph new_members_by_source_graph:StatsGraph languages_graph:StatsGraph messages_graph:StatsGraph actions_graph:StatsGraph top_hours_graph:StatsGraph weekdays_graph:StatsGraph top_posters:Vector<StatsGroupTopPoster> top_admins:Vector<StatsGroupTopAdmin> top_inviters:Vector<StatsGroupTopInviter> users:Vector<User> = stats.MegagroupStats;
|
||||
|
||||
globalPrivacySettings#c9d8df1c flags:# archive_and_mute_new_noncontact_peers:flags.0?true keep_archived_unmuted:flags.1?true keep_archived_folders:flags.2?true hide_read_marks:flags.3?true new_noncontact_peers_require_premium:flags.4?true noncontact_peers_paid_stars:flags.5?long = GlobalPrivacySettings;
|
||||
globalPrivacySettings#fe41b34f flags:# archive_and_mute_new_noncontact_peers:flags.0?true keep_archived_unmuted:flags.1?true keep_archived_folders:flags.2?true hide_read_marks:flags.3?true new_noncontact_peers_require_premium:flags.4?true display_gifts_button:flags.7?true noncontact_peers_paid_stars:flags.5?long disallowed_gifts:flags.6?DisallowedGiftsSettings = GlobalPrivacySettings;
|
||||
|
||||
help.countryCode#4203c5ef flags:# country_code:string prefixes:flags.0?Vector<string> patterns:flags.1?Vector<string> = help.CountryCode;
|
||||
|
||||
@ -1481,6 +1484,7 @@ inputInvoiceStarGift#e8625e92 flags:# hide_name:flags.0?true include_upgrade:fla
|
||||
inputInvoiceStarGiftUpgrade#4d818d5d flags:# keep_original_details:flags.0?true stargift:InputSavedStarGift = InputInvoice;
|
||||
inputInvoiceStarGiftTransfer#4a5f5bd9 stargift:InputSavedStarGift to_id:InputPeer = InputInvoice;
|
||||
inputInvoicePremiumGiftStars#dabab2ef flags:# user_id:InputUser months:int message:flags.0?TextWithEntities = InputInvoice;
|
||||
inputInvoiceBusinessBotTransferStars#f4997e42 bot:InputUser stars:long = InputInvoice;
|
||||
|
||||
payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice;
|
||||
|
||||
@ -1495,6 +1499,7 @@ inputStorePaymentPremiumGiveaway#160544ca flags:# only_new_subscribers:flags.0?t
|
||||
inputStorePaymentStarsTopup#dddd0f56 stars:long currency:string amount:long = InputStorePaymentPurpose;
|
||||
inputStorePaymentStarsGift#1d741ef7 user_id:InputUser stars:long currency:string amount:long = InputStorePaymentPurpose;
|
||||
inputStorePaymentStarsGiveaway#751f08fa flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.3?true stars:long boost_peer:InputPeer additional_peers:flags.1?Vector<InputPeer> countries_iso2:flags.2?Vector<string> prize_description:flags.4?string random_id:long until_date:int currency:string amount:long users:int = InputStorePaymentPurpose;
|
||||
inputStorePaymentAuthCode#9bb2636d flags:# restore:flags.0?true phone_number:string phone_code_hash:string currency:string amount:long = InputStorePaymentPurpose;
|
||||
|
||||
paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod;
|
||||
|
||||
@ -1753,7 +1758,7 @@ inputQuickReplyShortcutId#1190cf1 shortcut_id:int = InputQuickReplyShortcut;
|
||||
messages.quickReplies#c68d6695 quick_replies:Vector<QuickReply> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.QuickReplies;
|
||||
messages.quickRepliesNotModified#5f91eb5b = messages.QuickReplies;
|
||||
|
||||
connectedBot#bd068601 flags:# can_reply:flags.0?true bot_id:long recipients:BusinessBotRecipients = ConnectedBot;
|
||||
connectedBot#cd64636c flags:# bot_id:long recipients:BusinessBotRecipients rights:BusinessBotRights = ConnectedBot;
|
||||
|
||||
account.connectedBots#17d7f87b connected_bots:Vector<ConnectedBot> users:Vector<User> = account.ConnectedBots;
|
||||
|
||||
@ -1761,7 +1766,7 @@ messages.dialogFilters#2ad93719 flags:# tags_enabled:flags.0?true filters:Vector
|
||||
|
||||
birthday#6c8e1e06 flags:# day:int month:int year:flags.0?int = Birthday;
|
||||
|
||||
botBusinessConnection#896433b4 flags:# can_reply:flags.0?true disabled:flags.1?true connection_id:string user_id:long dc_id:int date:int = BotBusinessConnection;
|
||||
botBusinessConnection#8f34b2f5 flags:# disabled:flags.1?true connection_id:string user_id:long dc_id:int date:int rights:flags.2?BusinessBotRights = BotBusinessConnection;
|
||||
|
||||
inputBusinessIntro#9c469cd flags:# title:string description:string sticker:flags.0?InputDocument = InputBusinessIntro;
|
||||
|
||||
@ -1945,6 +1950,15 @@ requirementToContactEmpty#50a9839 = RequirementToContact;
|
||||
requirementToContactPremium#e581e4e9 = RequirementToContact;
|
||||
requirementToContactPaidMessages#b4f67e93 stars_amount:long = RequirementToContact;
|
||||
|
||||
businessBotRights#a0624cf7 flags:# reply:flags.0?true read_messages:flags.1?true delete_sent_messages:flags.2?true delete_received_messages:flags.3?true edit_name:flags.4?true edit_bio:flags.5?true edit_profile_photo:flags.6?true edit_username:flags.7?true view_gifts:flags.8?true sell_gifts:flags.9?true change_gift_settings:flags.10?true transfer_and_upgrade_gifts:flags.11?true transfer_stars:flags.12?true manage_stories:flags.13?true = BusinessBotRights;
|
||||
|
||||
disallowedGiftsSettings#71f276c4 flags:# disallow_unlimited_stargifts:flags.0?true disallow_limited_stargifts:flags.1?true disallow_unique_stargifts:flags.2?true disallow_premium_gifts:flags.3?true = DisallowedGiftsSettings;
|
||||
|
||||
sponsoredPeer#c69708d3 flags:# random_id:bytes peer:Peer sponsor_info:flags.0?string additional_info:flags.1?string = SponsoredPeer;
|
||||
|
||||
contacts.sponsoredPeersEmpty#ea32b4b1 = contacts.SponsoredPeers;
|
||||
contacts.sponsoredPeers#eb032884 peers:Vector<SponsoredPeer> chats:Vector<Chat> users:Vector<User> = contacts.SponsoredPeers;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
@ -1956,7 +1970,7 @@ invokeWithMessagesRange#365275f2 {X:Type} range:MessageRange query:!X = X;
|
||||
invokeWithTakeout#aca9fd2e {X:Type} takeout_id:long query:!X = X;
|
||||
invokeWithBusinessConnection#dd289f8e {X:Type} connection_id:string query:!X = X;
|
||||
invokeWithGooglePlayIntegrity#1df92984 {X:Type} nonce:string token:string query:!X = X;
|
||||
invokeWithApnsSecret#dae54f8 {X:Type} nonce:string secret:string query:!X = X;
|
||||
invokeWithApnsSecret#0dae54f8 {X:Type} nonce:string secret:string query:!X = X;
|
||||
invokeWithReCaptcha#adbb0f94 {X:Type} token:string query:!X = X;
|
||||
|
||||
auth.sendCode#a677244f phone_number:string api_id:int api_hash:string settings:CodeSettings = auth.SentCode;
|
||||
@ -2079,7 +2093,7 @@ account.updateBusinessWorkHours#4b00e066 flags:# business_work_hours:flags.0?Bus
|
||||
account.updateBusinessLocation#9e6b131a flags:# geo_point:flags.1?InputGeoPoint address:flags.0?string = Bool;
|
||||
account.updateBusinessGreetingMessage#66cdafc4 flags:# message:flags.0?InputBusinessGreetingMessage = Bool;
|
||||
account.updateBusinessAwayMessage#a26a7fa5 flags:# message:flags.0?InputBusinessAwayMessage = Bool;
|
||||
account.updateConnectedBot#43d8521d flags:# can_reply:flags.0?true deleted:flags.1?true bot:InputUser recipients:InputBusinessBotRecipients = Updates;
|
||||
account.updateConnectedBot#66a08c7e flags:# deleted:flags.1?true rights:flags.0?BusinessBotRights bot:InputUser recipients:InputBusinessBotRecipients = Updates;
|
||||
account.getConnectedBots#4ea4c80f = account.ConnectedBots;
|
||||
account.getBotBusinessConnection#76a86270 connection_id:string = Updates;
|
||||
account.updateBusinessIntro#a614d034 flags:# intro:flags.0?InputBusinessIntro = Bool;
|
||||
@ -2130,6 +2144,7 @@ contacts.importContactToken#13005788 token:string = User;
|
||||
contacts.editCloseFriends#ba6705f0 id:Vector<long> = Bool;
|
||||
contacts.setBlocked#94c65c76 flags:# my_stories_from:flags.0?true id:Vector<InputPeer> limit:int = Bool;
|
||||
contacts.getBirthdays#daeda864 = contacts.ContactBirthdays;
|
||||
contacts.getSponsoredPeers#b6c8c393 q:string = contacts.SponsoredPeers;
|
||||
|
||||
messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
|
||||
messages.getDialogs#a0f4cb4f flags:# exclude_pinned:flags.0?true folder_id:flags.1?int offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:long = messages.Dialogs;
|
||||
@ -2348,9 +2363,9 @@ messages.requestMainWebView#c9e01e7b flags:# compact:flags.7?true fullscreen:fla
|
||||
messages.sendPaidReaction#58bbcb50 flags:# peer:InputPeer msg_id:int count:int random_id:long private:flags.0?PaidReactionPrivacy = Updates;
|
||||
messages.togglePaidReactionPrivacy#435885b5 peer:InputPeer msg_id:int private:PaidReactionPrivacy = Bool;
|
||||
messages.getPaidReactionPrivacy#472455aa = Updates;
|
||||
messages.viewSponsoredMessage#673ad8f1 peer:InputPeer random_id:bytes = Bool;
|
||||
messages.clickSponsoredMessage#f093465 flags:# media:flags.0?true fullscreen:flags.1?true peer:InputPeer random_id:bytes = Bool;
|
||||
messages.reportSponsoredMessage#1af3dbb8 peer:InputPeer random_id:bytes option:bytes = channels.SponsoredMessageReportResult;
|
||||
messages.viewSponsoredMessage#269e3643 random_id:bytes = Bool;
|
||||
messages.clickSponsoredMessage#8235057e flags:# media:flags.0?true fullscreen:flags.1?true random_id:bytes = Bool;
|
||||
messages.reportSponsoredMessage#12cbf0c4 random_id:bytes option:bytes = channels.SponsoredMessageReportResult;
|
||||
messages.getSponsoredMessages#9bd2f439 peer:InputPeer = messages.SponsoredMessages;
|
||||
messages.savePreparedInlineMessage#f21f7f2f flags:# result:InputBotInlineResult user_id:InputUser peer_types:flags.0?Vector<InlineQueryPeerType> = messages.BotPreparedInlineMessage;
|
||||
messages.getPreparedInlineMessage#857ebdb8 bot:InputUser id:string = messages.PreparedInlineMessage;
|
||||
@ -2506,7 +2521,6 @@ payments.getBankCardData#2e79d779 number:string = payments.BankCardData;
|
||||
payments.exportInvoice#f91b065 invoice_media:InputMedia = payments.ExportedInvoice;
|
||||
payments.assignAppStoreTransaction#80ed747d receipt:bytes purpose:InputStorePaymentPurpose = Updates;
|
||||
payments.assignPlayMarketTransaction#dffd50d3 receipt:DataJSON purpose:InputStorePaymentPurpose = Updates;
|
||||
payments.canPurchasePremium#9fc19eb6 purpose:InputStorePaymentPurpose = Bool;
|
||||
payments.getPremiumGiftCodeOptions#2757ba54 flags:# boost_peer:flags.0?InputPeer = Vector<PremiumGiftCodeOption>;
|
||||
payments.checkGiftCode#8e51b4c1 slug:string = payments.CheckedGiftCode;
|
||||
payments.applyGiftCode#f6e26854 slug:string = Updates;
|
||||
@ -2544,6 +2558,7 @@ payments.getSavedStarGift#b455a106 stargift:Vector<InputSavedStarGift> = payment
|
||||
payments.getStarGiftWithdrawalUrl#d06e93a8 stargift:InputSavedStarGift password:InputCheckPasswordSRP = payments.StarGiftWithdrawalUrl;
|
||||
payments.toggleChatStarGiftNotifications#60eaefa1 flags:# enabled:flags.0?true peer:InputPeer = Bool;
|
||||
payments.toggleStarGiftsPinnedToTop#1513e7b0 peer:InputPeer stargift:Vector<InputSavedStarGift> = Bool;
|
||||
payments.canPurchaseStore#4fdc5ea7 purpose:InputStorePaymentPurpose = Bool;
|
||||
|
||||
stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true emojis:flags.5?true text_color:flags.6?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector<InputStickerSetItem> software:flags.3?string = messages.StickerSet;
|
||||
stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet;
|
||||
|
||||
@ -127,168 +127,169 @@ $icons-map: (
|
||||
"forums": "\f15a",
|
||||
"forward": "\f15b",
|
||||
"fragment": "\f15c",
|
||||
"fullscreen": "\f15d",
|
||||
"gifs": "\f15e",
|
||||
"gift": "\f15f",
|
||||
"group-filled": "\f160",
|
||||
"group": "\f161",
|
||||
"grouped-disable": "\f162",
|
||||
"grouped": "\f163",
|
||||
"hand-stop": "\f164",
|
||||
"hashtag": "\f165",
|
||||
"heart-outline": "\f166",
|
||||
"heart": "\f167",
|
||||
"help": "\f168",
|
||||
"info-filled": "\f169",
|
||||
"info": "\f16a",
|
||||
"install": "\f16b",
|
||||
"italic": "\f16c",
|
||||
"key": "\f16d",
|
||||
"keyboard": "\f16e",
|
||||
"lamp": "\f16f",
|
||||
"language": "\f170",
|
||||
"large-pause": "\f171",
|
||||
"large-play": "\f172",
|
||||
"link-badge": "\f173",
|
||||
"link-broken": "\f174",
|
||||
"link": "\f175",
|
||||
"location": "\f176",
|
||||
"lock-badge": "\f177",
|
||||
"lock": "\f178",
|
||||
"logout": "\f179",
|
||||
"loop": "\f17a",
|
||||
"mention": "\f17b",
|
||||
"message-failed": "\f17c",
|
||||
"message-pending": "\f17d",
|
||||
"message-read": "\f17e",
|
||||
"message-succeeded": "\f17f",
|
||||
"message": "\f180",
|
||||
"microphone-alt": "\f181",
|
||||
"microphone": "\f182",
|
||||
"monospace": "\f183",
|
||||
"more-circle": "\f184",
|
||||
"more": "\f185",
|
||||
"move-caption-down": "\f186",
|
||||
"move-caption-up": "\f187",
|
||||
"mute": "\f188",
|
||||
"muted": "\f189",
|
||||
"my-notes": "\f18a",
|
||||
"new-chat-filled": "\f18b",
|
||||
"next": "\f18c",
|
||||
"nochannel": "\f18d",
|
||||
"noise-suppression": "\f18e",
|
||||
"non-contacts": "\f18f",
|
||||
"one-filled": "\f190",
|
||||
"open-in-new-tab": "\f191",
|
||||
"password-off": "\f192",
|
||||
"pause": "\f193",
|
||||
"permissions": "\f194",
|
||||
"phone-discard-outline": "\f195",
|
||||
"phone-discard": "\f196",
|
||||
"phone": "\f197",
|
||||
"photo": "\f198",
|
||||
"pin-badge": "\f199",
|
||||
"pin-list": "\f19a",
|
||||
"pin": "\f19b",
|
||||
"pinned-chat": "\f19c",
|
||||
"pinned-message": "\f19d",
|
||||
"pip": "\f19e",
|
||||
"play-story": "\f19f",
|
||||
"play": "\f1a0",
|
||||
"poll": "\f1a1",
|
||||
"previous": "\f1a2",
|
||||
"privacy-policy": "\f1a3",
|
||||
"proof-of-ownership": "\f1a4",
|
||||
"quote-text": "\f1a5",
|
||||
"quote": "\f1a6",
|
||||
"radial-badge": "\f1a7",
|
||||
"readchats": "\f1a8",
|
||||
"recent": "\f1a9",
|
||||
"reload": "\f1aa",
|
||||
"remove-quote": "\f1ab",
|
||||
"remove": "\f1ac",
|
||||
"reopen-topic": "\f1ad",
|
||||
"replace": "\f1ae",
|
||||
"replies": "\f1af",
|
||||
"reply-filled": "\f1b0",
|
||||
"reply": "\f1b1",
|
||||
"revenue-split": "\f1b2",
|
||||
"revote": "\f1b3",
|
||||
"save-story": "\f1b4",
|
||||
"saved-messages": "\f1b5",
|
||||
"schedule": "\f1b6",
|
||||
"search": "\f1b7",
|
||||
"select": "\f1b8",
|
||||
"send-outline": "\f1b9",
|
||||
"send": "\f1ba",
|
||||
"settings-filled": "\f1bb",
|
||||
"settings": "\f1bc",
|
||||
"share-filled": "\f1bd",
|
||||
"share-screen-outlined": "\f1be",
|
||||
"share-screen-stop": "\f1bf",
|
||||
"share-screen": "\f1c0",
|
||||
"show-message": "\f1c1",
|
||||
"sidebar": "\f1c2",
|
||||
"skip-next": "\f1c3",
|
||||
"skip-previous": "\f1c4",
|
||||
"smallscreen": "\f1c5",
|
||||
"smile": "\f1c6",
|
||||
"sort": "\f1c7",
|
||||
"speaker-muted-story": "\f1c8",
|
||||
"speaker-outline": "\f1c9",
|
||||
"speaker-story": "\f1ca",
|
||||
"speaker": "\f1cb",
|
||||
"spoiler-disable": "\f1cc",
|
||||
"spoiler": "\f1cd",
|
||||
"sport": "\f1ce",
|
||||
"star": "\f1cf",
|
||||
"stars-lock": "\f1d0",
|
||||
"stats": "\f1d1",
|
||||
"stealth-future": "\f1d2",
|
||||
"stealth-past": "\f1d3",
|
||||
"stickers": "\f1d4",
|
||||
"stop-raising-hand": "\f1d5",
|
||||
"stop": "\f1d6",
|
||||
"story-caption": "\f1d7",
|
||||
"story-expired": "\f1d8",
|
||||
"story-priority": "\f1d9",
|
||||
"story-reply": "\f1da",
|
||||
"strikethrough": "\f1db",
|
||||
"tag-add": "\f1dc",
|
||||
"tag-crossed": "\f1dd",
|
||||
"tag-filter": "\f1de",
|
||||
"tag-name": "\f1df",
|
||||
"tag": "\f1e0",
|
||||
"timer": "\f1e1",
|
||||
"toncoin": "\f1e2",
|
||||
"trade": "\f1e3",
|
||||
"transcribe": "\f1e4",
|
||||
"truck": "\f1e5",
|
||||
"unarchive": "\f1e6",
|
||||
"underlined": "\f1e7",
|
||||
"unique-profile": "\f1e8",
|
||||
"unlock-badge": "\f1e9",
|
||||
"unlock": "\f1ea",
|
||||
"unmute": "\f1eb",
|
||||
"unpin": "\f1ec",
|
||||
"unread": "\f1ed",
|
||||
"up": "\f1ee",
|
||||
"user-filled": "\f1ef",
|
||||
"user-online": "\f1f0",
|
||||
"user": "\f1f1",
|
||||
"video-outlined": "\f1f2",
|
||||
"video-stop": "\f1f3",
|
||||
"video": "\f1f4",
|
||||
"view-once": "\f1f5",
|
||||
"voice-chat": "\f1f6",
|
||||
"volume-1": "\f1f7",
|
||||
"volume-2": "\f1f8",
|
||||
"volume-3": "\f1f9",
|
||||
"web": "\f1fa",
|
||||
"webapp": "\f1fb",
|
||||
"word-wrap": "\f1fc",
|
||||
"zoom-in": "\f1fd",
|
||||
"zoom-out": "\f1fe",
|
||||
"frozen-time": "\f15d",
|
||||
"fullscreen": "\f15e",
|
||||
"gifs": "\f15f",
|
||||
"gift": "\f160",
|
||||
"group-filled": "\f161",
|
||||
"group": "\f162",
|
||||
"grouped-disable": "\f163",
|
||||
"grouped": "\f164",
|
||||
"hand-stop": "\f165",
|
||||
"hashtag": "\f166",
|
||||
"heart-outline": "\f167",
|
||||
"heart": "\f168",
|
||||
"help": "\f169",
|
||||
"info-filled": "\f16a",
|
||||
"info": "\f16b",
|
||||
"install": "\f16c",
|
||||
"italic": "\f16d",
|
||||
"key": "\f16e",
|
||||
"keyboard": "\f16f",
|
||||
"lamp": "\f170",
|
||||
"language": "\f171",
|
||||
"large-pause": "\f172",
|
||||
"large-play": "\f173",
|
||||
"link-badge": "\f174",
|
||||
"link-broken": "\f175",
|
||||
"link": "\f176",
|
||||
"location": "\f177",
|
||||
"lock-badge": "\f178",
|
||||
"lock": "\f179",
|
||||
"logout": "\f17a",
|
||||
"loop": "\f17b",
|
||||
"mention": "\f17c",
|
||||
"message-failed": "\f17d",
|
||||
"message-pending": "\f17e",
|
||||
"message-read": "\f17f",
|
||||
"message-succeeded": "\f180",
|
||||
"message": "\f181",
|
||||
"microphone-alt": "\f182",
|
||||
"microphone": "\f183",
|
||||
"monospace": "\f184",
|
||||
"more-circle": "\f185",
|
||||
"more": "\f186",
|
||||
"move-caption-down": "\f187",
|
||||
"move-caption-up": "\f188",
|
||||
"mute": "\f189",
|
||||
"muted": "\f18a",
|
||||
"my-notes": "\f18b",
|
||||
"new-chat-filled": "\f18c",
|
||||
"next": "\f18d",
|
||||
"nochannel": "\f18e",
|
||||
"noise-suppression": "\f18f",
|
||||
"non-contacts": "\f190",
|
||||
"one-filled": "\f191",
|
||||
"open-in-new-tab": "\f192",
|
||||
"password-off": "\f193",
|
||||
"pause": "\f194",
|
||||
"permissions": "\f195",
|
||||
"phone-discard-outline": "\f196",
|
||||
"phone-discard": "\f197",
|
||||
"phone": "\f198",
|
||||
"photo": "\f199",
|
||||
"pin-badge": "\f19a",
|
||||
"pin-list": "\f19b",
|
||||
"pin": "\f19c",
|
||||
"pinned-chat": "\f19d",
|
||||
"pinned-message": "\f19e",
|
||||
"pip": "\f19f",
|
||||
"play-story": "\f1a0",
|
||||
"play": "\f1a1",
|
||||
"poll": "\f1a2",
|
||||
"previous": "\f1a3",
|
||||
"privacy-policy": "\f1a4",
|
||||
"proof-of-ownership": "\f1a5",
|
||||
"quote-text": "\f1a6",
|
||||
"quote": "\f1a7",
|
||||
"radial-badge": "\f1a8",
|
||||
"readchats": "\f1a9",
|
||||
"recent": "\f1aa",
|
||||
"reload": "\f1ab",
|
||||
"remove-quote": "\f1ac",
|
||||
"remove": "\f1ad",
|
||||
"reopen-topic": "\f1ae",
|
||||
"replace": "\f1af",
|
||||
"replies": "\f1b0",
|
||||
"reply-filled": "\f1b1",
|
||||
"reply": "\f1b2",
|
||||
"revenue-split": "\f1b3",
|
||||
"revote": "\f1b4",
|
||||
"save-story": "\f1b5",
|
||||
"saved-messages": "\f1b6",
|
||||
"schedule": "\f1b7",
|
||||
"search": "\f1b8",
|
||||
"select": "\f1b9",
|
||||
"send-outline": "\f1ba",
|
||||
"send": "\f1bb",
|
||||
"settings-filled": "\f1bc",
|
||||
"settings": "\f1bd",
|
||||
"share-filled": "\f1be",
|
||||
"share-screen-outlined": "\f1bf",
|
||||
"share-screen-stop": "\f1c0",
|
||||
"share-screen": "\f1c1",
|
||||
"show-message": "\f1c2",
|
||||
"sidebar": "\f1c3",
|
||||
"skip-next": "\f1c4",
|
||||
"skip-previous": "\f1c5",
|
||||
"smallscreen": "\f1c6",
|
||||
"smile": "\f1c7",
|
||||
"sort": "\f1c8",
|
||||
"speaker-muted-story": "\f1c9",
|
||||
"speaker-outline": "\f1ca",
|
||||
"speaker-story": "\f1cb",
|
||||
"speaker": "\f1cc",
|
||||
"spoiler-disable": "\f1cd",
|
||||
"spoiler": "\f1ce",
|
||||
"sport": "\f1cf",
|
||||
"star": "\f1d0",
|
||||
"stars-lock": "\f1d1",
|
||||
"stats": "\f1d2",
|
||||
"stealth-future": "\f1d3",
|
||||
"stealth-past": "\f1d4",
|
||||
"stickers": "\f1d5",
|
||||
"stop-raising-hand": "\f1d6",
|
||||
"stop": "\f1d7",
|
||||
"story-caption": "\f1d8",
|
||||
"story-expired": "\f1d9",
|
||||
"story-priority": "\f1da",
|
||||
"story-reply": "\f1db",
|
||||
"strikethrough": "\f1dc",
|
||||
"tag-add": "\f1dd",
|
||||
"tag-crossed": "\f1de",
|
||||
"tag-filter": "\f1df",
|
||||
"tag-name": "\f1e0",
|
||||
"tag": "\f1e1",
|
||||
"timer": "\f1e2",
|
||||
"toncoin": "\f1e3",
|
||||
"trade": "\f1e4",
|
||||
"transcribe": "\f1e5",
|
||||
"truck": "\f1e6",
|
||||
"unarchive": "\f1e7",
|
||||
"underlined": "\f1e8",
|
||||
"unique-profile": "\f1e9",
|
||||
"unlock-badge": "\f1ea",
|
||||
"unlock": "\f1eb",
|
||||
"unmute": "\f1ec",
|
||||
"unpin": "\f1ed",
|
||||
"unread": "\f1ee",
|
||||
"up": "\f1ef",
|
||||
"user-filled": "\f1f0",
|
||||
"user-online": "\f1f1",
|
||||
"user": "\f1f2",
|
||||
"video-outlined": "\f1f3",
|
||||
"video-stop": "\f1f4",
|
||||
"video": "\f1f5",
|
||||
"view-once": "\f1f6",
|
||||
"voice-chat": "\f1f7",
|
||||
"volume-1": "\f1f8",
|
||||
"volume-2": "\f1f9",
|
||||
"volume-3": "\f1fa",
|
||||
"web": "\f1fb",
|
||||
"webapp": "\f1fc",
|
||||
"word-wrap": "\f1fd",
|
||||
"zoom-in": "\f1fe",
|
||||
"zoom-out": "\f1ff",
|
||||
);
|
||||
|
||||
.icon-active-sessions::before {
|
||||
@ -567,6 +568,9 @@ $icons-map: (
|
||||
.icon-fragment::before {
|
||||
content: map.get($icons-map, "fragment");
|
||||
}
|
||||
.icon-frozen-time::before {
|
||||
content: map.get($icons-map, "frozen-time");
|
||||
}
|
||||
.icon-fullscreen::before {
|
||||
content: map.get($icons-map, "fullscreen");
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -91,6 +91,7 @@ export type FontIconName =
|
||||
| 'forums'
|
||||
| 'forward'
|
||||
| 'fragment'
|
||||
| 'frozen-time'
|
||||
| 'fullscreen'
|
||||
| 'gifs'
|
||||
| 'gift'
|
||||
|
||||
30
src/types/language.d.ts
vendored
30
src/types/language.d.ts
vendored
@ -1458,9 +1458,24 @@ export interface LangPair {
|
||||
'StoryTooltipReactionSent': undefined;
|
||||
'StarsNeededTextSendPaidMessages': undefined;
|
||||
'PaidMessageTransactionTotal': undefined;
|
||||
'TitleFrozenAccount': undefined;
|
||||
'SubtitleFrozenAccount': undefined;
|
||||
'ComposerTitleFrozenAccount': undefined;
|
||||
'ComposerSubtitleFrozenAccount': undefined;
|
||||
'DescriptionRestrictedMedia': undefined;
|
||||
'DescriptionScheduledPaidMediaNotAllowed': undefined;
|
||||
'DescriptionScheduledPaidMessagesNotAllowed': undefined;
|
||||
'FrozenAccountModalTitle': undefined;
|
||||
'FrozenAccountViolationTitle': undefined;
|
||||
'FrozenAccountViolationSubtitle': undefined;
|
||||
'FrozenAccountReadOnlyTitle': undefined;
|
||||
'FrozenAccountReadOnlySubtitle': undefined;
|
||||
'FrozenAccountAppealTitle': undefined;
|
||||
'ButtonAppeal': undefined;
|
||||
'ButtonUnderstood': undefined;
|
||||
'ActionPaidMessageGroupPriceFree': undefined;
|
||||
'NotificationTitleNotSupportedInFrozenAccount': undefined;
|
||||
'NotificationMessageNotSupportedInFrozenAccount': undefined;
|
||||
}
|
||||
|
||||
export interface LangPairWithVariables<V extends unknown = LangVariable> {
|
||||
@ -2346,6 +2361,21 @@ export interface LangPairWithVariables<V extends unknown = LangVariable> {
|
||||
'PaidMessageTransactionDescription': {
|
||||
'percent': V;
|
||||
};
|
||||
'FrozenAccountAppealSubtitle': {
|
||||
'botLink': V;
|
||||
'date': V;
|
||||
};
|
||||
'ActionPaidMessageGroupPrice': {
|
||||
'stars': V;
|
||||
};
|
||||
'ApiMessageActionPaidMessagesRefundedOutgoing': {
|
||||
'stars': V;
|
||||
'user': V;
|
||||
};
|
||||
'ApiMessageActionPaidMessagesRefundedIncoming': {
|
||||
'user': V;
|
||||
'stars': V;
|
||||
};
|
||||
}
|
||||
|
||||
export interface LangPairPlural {
|
||||
|
||||
@ -147,6 +147,14 @@ export function tryParseDeepLink(link: string): DeepLink | undefined {
|
||||
}
|
||||
}
|
||||
|
||||
export function getUsernameFromDeepLink(url: string) {
|
||||
const deepLink = tryParseDeepLink(url);
|
||||
if (deepLink?.type === 'publicUsernameOrBotLink') {
|
||||
return deepLink.username;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function parseDeepLink(url: string) {
|
||||
const correctUrl = ensureProtocol(url);
|
||||
if (!correctUrl) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user