Settings Privacy: Implement account self destruction (#5939)
Co-authored-by: zubiden <19638254+zubiden@users.noreply.github.com>
This commit is contained in:
parent
f2d14ca78f
commit
f1a538ed8e
@ -99,3 +99,29 @@ export function toggleSponsoredMessages({
|
|||||||
shouldReturnTrue: true,
|
shouldReturnTrue: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildApiAccountDays(ttl: GramJs.AccountDaysTTL): { days: number } {
|
||||||
|
return {
|
||||||
|
days: ttl.days,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildApiAccountDaysTTL(days: number): GramJs.AccountDaysTTL {
|
||||||
|
return new GramJs.AccountDaysTTL({
|
||||||
|
days,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchAccountTTL() {
|
||||||
|
const result = await invokeRequest(new GramJs.account.GetAccountTTL());
|
||||||
|
if (!result) return undefined;
|
||||||
|
return buildApiAccountDays(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setAccountTTL({ days }: { days: number }) {
|
||||||
|
return invokeRequest(new GramJs.account.SetAccountTTL({
|
||||||
|
ttl: buildApiAccountDaysTTL(days),
|
||||||
|
}), {
|
||||||
|
shouldReturnTrue: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@ -1552,6 +1552,10 @@
|
|||||||
"CloseMiniApps" = "Close Mini Apps";
|
"CloseMiniApps" = "Close Mini Apps";
|
||||||
"DoNotAskAgain" = "Don't ask again";
|
"DoNotAskAgain" = "Don't ask again";
|
||||||
"PaymentInfoDone" = "Proceed to checkout";
|
"PaymentInfoDone" = "Proceed to checkout";
|
||||||
|
"DeleteMyAccount" = "Delete my account";
|
||||||
|
"DeleteAccountIfAwayFor" = "If away for";
|
||||||
|
"SelfDestructTitle" = "Account self-destruction";
|
||||||
|
"SelfDestructSessionsDescription" = "If you don't come online from a specific session at least once within this period, it will be terminated.";
|
||||||
"EmojiStatusAccessText" = "**{name}** requests access to set your **emoji status**. You will be able to revoke this access in the profile page of **{name}**.";
|
"EmojiStatusAccessText" = "**{name}** requests access to set your **emoji status**. You will be able to revoke this access in the profile page of **{name}**.";
|
||||||
"VideoConversionTitle" = "Improving Video...";
|
"VideoConversionTitle" = "Improving Video...";
|
||||||
"VideoConversionText" = "The video will be published after it's optimized for the best viewing experience.";
|
"VideoConversionText" = "The video will be published after it's optimized for the best viewing experience.";
|
||||||
|
|||||||
@ -23,6 +23,7 @@ export { default as StatusPickerMenu } from '../components/left/main/StatusPicke
|
|||||||
export { default as SuggestedStatusModal } from '../components/modals/suggestedStatus/SuggestedStatusModal';
|
export { default as SuggestedStatusModal } from '../components/modals/suggestedStatus/SuggestedStatusModal';
|
||||||
export { default as BoostModal } from '../components/modals/boost/BoostModal';
|
export { default as BoostModal } from '../components/modals/boost/BoostModal';
|
||||||
export { default as GiftCodeModal } from '../components/modals/giftcode/GiftCodeModal';
|
export { default as GiftCodeModal } from '../components/modals/giftcode/GiftCodeModal';
|
||||||
|
export { default as DeleteAccountModal } from '../components/modals/deleteAccount/DeleteAccountModal';
|
||||||
export { default as ChatlistModal } from '../components/modals/chatlist/ChatlistModal';
|
export { default as ChatlistModal } from '../components/modals/chatlist/ChatlistModal';
|
||||||
export { default as ChatInviteModal } from '../components/modals/chatInvite/ChatInviteModal';
|
export { default as ChatInviteModal } from '../components/modals/chatInvite/ChatInviteModal';
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import type { FC } from '../../../lib/teact/teact';
|
import type { FC } from '../../../lib/teact/teact';
|
||||||
|
import { useMemo } from '../../../lib/teact/teact';
|
||||||
import React, { memo, useCallback, useEffect } from '../../../lib/teact/teact';
|
import React, { memo, useCallback, useEffect } from '../../../lib/teact/teact';
|
||||||
import { getActions, withGlobal } from '../../../global';
|
import { getActions, withGlobal } from '../../../global';
|
||||||
|
|
||||||
@ -6,14 +7,17 @@ import type { ApiPrivacySettings } from '../../../api/types';
|
|||||||
import type { GlobalState } from '../../../global/types';
|
import type { GlobalState } from '../../../global/types';
|
||||||
import { SettingsScreens } from '../../../types';
|
import { SettingsScreens } from '../../../types';
|
||||||
|
|
||||||
|
import { ACCOUNT_TTL_OPTIONS } from '../../../config.ts';
|
||||||
import {
|
import {
|
||||||
selectCanSetPasscode, selectIsCurrentUserFrozen,
|
selectCanSetPasscode, selectIsCurrentUserFrozen,
|
||||||
selectIsCurrentUserPremium,
|
selectIsCurrentUserPremium,
|
||||||
} from '../../../global/selectors';
|
} from '../../../global/selectors';
|
||||||
import { selectSharedSettings } from '../../../global/selectors/sharedState';
|
import { selectSharedSettings } from '../../../global/selectors/sharedState';
|
||||||
|
import { getClosestEntry } from '../../../util/getClosestEntry.ts';
|
||||||
|
|
||||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
|
import useLastCallback from '../../../hooks/useLastCallback.ts';
|
||||||
import useOldLang from '../../../hooks/useOldLang';
|
import useOldLang from '../../../hooks/useOldLang';
|
||||||
|
|
||||||
import StarIcon from '../../common/icons/StarIcon';
|
import StarIcon from '../../common/icons/StarIcon';
|
||||||
@ -41,8 +45,11 @@ type StateProps = {
|
|||||||
canDisplayChatInTitle?: boolean;
|
canDisplayChatInTitle?: boolean;
|
||||||
isCurrentUserFrozen?: boolean;
|
isCurrentUserFrozen?: boolean;
|
||||||
privacy: GlobalState['settings']['privacy'];
|
privacy: GlobalState['settings']['privacy'];
|
||||||
|
accountDaysTtl?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const DAYS_PER_MONTH = 30;
|
||||||
|
|
||||||
const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
||||||
isActive,
|
isActive,
|
||||||
isCurrentUserPremium,
|
isCurrentUserPremium,
|
||||||
@ -61,8 +68,10 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
|||||||
privacy,
|
privacy,
|
||||||
onReset,
|
onReset,
|
||||||
isCurrentUserFrozen,
|
isCurrentUserFrozen,
|
||||||
|
accountDaysTtl,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
|
openDeleteAccountModal,
|
||||||
loadPrivacySettings,
|
loadPrivacySettings,
|
||||||
loadBlockedUsers,
|
loadBlockedUsers,
|
||||||
loadContentSettings,
|
loadContentSettings,
|
||||||
@ -72,6 +81,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
|||||||
loadWebAuthorizations,
|
loadWebAuthorizations,
|
||||||
setSharedSettingOption,
|
setSharedSettingOption,
|
||||||
openSettingsScreen,
|
openSettingsScreen,
|
||||||
|
loadAccountDaysTtl,
|
||||||
} = getActions();
|
} = getActions();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -86,6 +96,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isActive && !isCurrentUserFrozen) {
|
if (isActive && !isCurrentUserFrozen) {
|
||||||
loadGlobalPrivacySettings();
|
loadGlobalPrivacySettings();
|
||||||
|
loadAccountDaysTtl();
|
||||||
}
|
}
|
||||||
}, [isActive, isCurrentUserFrozen, loadGlobalPrivacySettings]);
|
}, [isActive, isCurrentUserFrozen, loadGlobalPrivacySettings]);
|
||||||
|
|
||||||
@ -113,6 +124,16 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
|||||||
updateContentSettings({ isSensitiveEnabled: isChecked });
|
updateContentSettings({ isSensitiveEnabled: isChecked });
|
||||||
}, [updateContentSettings]);
|
}, [updateContentSettings]);
|
||||||
|
|
||||||
|
const handleOpenDeleteAccountModal = useLastCallback(() => {
|
||||||
|
if (!accountDaysTtl) return;
|
||||||
|
openDeleteAccountModal({ days: accountDaysTtl });
|
||||||
|
});
|
||||||
|
|
||||||
|
const dayOption = useMemo(() => {
|
||||||
|
if (!accountDaysTtl) return undefined;
|
||||||
|
return getClosestEntry(ACCOUNT_TTL_OPTIONS, accountDaysTtl / DAYS_PER_MONTH).toString();
|
||||||
|
}, [accountDaysTtl]);
|
||||||
|
|
||||||
function getVisibilityValue(setting?: ApiPrivacySettings) {
|
function getVisibilityValue(setting?: ApiPrivacySettings) {
|
||||||
if (!setting) return oldLang('Loading');
|
if (!setting) return oldLang('Loading');
|
||||||
|
|
||||||
@ -402,6 +423,21 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
|||||||
onCheck={handleChatInTitleChange}
|
onCheck={handleChatInTitleChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="settings-item">
|
||||||
|
<h4 className="settings-item-header" dir={oldLang.isRtl ? 'rtl' : undefined}>
|
||||||
|
{lang('DeleteMyAccount')}
|
||||||
|
</h4>
|
||||||
|
<ListItem
|
||||||
|
narrow
|
||||||
|
onClick={handleOpenDeleteAccountModal}
|
||||||
|
>
|
||||||
|
{lang('DeleteAccountIfAwayFor')}
|
||||||
|
<span className="settings-item__current-value">
|
||||||
|
{lang('Months', { count: dayOption }, { pluralValue: 1 })}
|
||||||
|
</span>
|
||||||
|
</ListItem>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -415,6 +451,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
shouldNewNonContactPeersRequirePremium, nonContactPeersPaidStars,
|
shouldNewNonContactPeersRequirePremium, nonContactPeersPaidStars,
|
||||||
},
|
},
|
||||||
privacy,
|
privacy,
|
||||||
|
accountDaysTtl,
|
||||||
},
|
},
|
||||||
blocked,
|
blocked,
|
||||||
passcode: {
|
passcode: {
|
||||||
@ -443,6 +480,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
canDisplayChatInTitle,
|
canDisplayChatInTitle,
|
||||||
canSetPasscode: selectCanSetPasscode(global),
|
canSetPasscode: selectCanSetPasscode(global),
|
||||||
isCurrentUserFrozen,
|
isCurrentUserFrozen,
|
||||||
|
accountDaysTtl,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(SettingsPrivacy));
|
)(SettingsPrivacy));
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import BoostModal from './boost/BoostModal.async';
|
|||||||
import ChatInviteModal from './chatInvite/ChatInviteModal.async';
|
import ChatInviteModal from './chatInvite/ChatInviteModal.async';
|
||||||
import ChatlistModal from './chatlist/ChatlistModal.async';
|
import ChatlistModal from './chatlist/ChatlistModal.async';
|
||||||
import CollectibleInfoModal from './collectible/CollectibleInfoModal.async';
|
import CollectibleInfoModal from './collectible/CollectibleInfoModal.async';
|
||||||
|
import DeleteAccountModal from './deleteAccount/DeleteAccountModal.async';
|
||||||
import EmojiStatusAccessModal from './emojiStatusAccess/EmojiStatusAccessModal.async';
|
import EmojiStatusAccessModal from './emojiStatusAccess/EmojiStatusAccessModal.async';
|
||||||
import FrozenAccountModal from './frozenAccount/FrozenAccountModal.async';
|
import FrozenAccountModal from './frozenAccount/FrozenAccountModal.async';
|
||||||
import PremiumGiftModal from './gift/GiftModal.async';
|
import PremiumGiftModal from './gift/GiftModal.async';
|
||||||
@ -82,7 +83,8 @@ type ModalKey = keyof Pick<TabState,
|
|||||||
'giftStatusInfoModal' |
|
'giftStatusInfoModal' |
|
||||||
'giftTransferModal' |
|
'giftTransferModal' |
|
||||||
'chatRefundModal' |
|
'chatRefundModal' |
|
||||||
'isFrozenAccountModalOpen'
|
'isFrozenAccountModalOpen' |
|
||||||
|
'deleteAccountModal'
|
||||||
>;
|
>;
|
||||||
|
|
||||||
type StateProps = {
|
type StateProps = {
|
||||||
@ -135,6 +137,7 @@ const MODALS: ModalRegistry = {
|
|||||||
giftTransferModal: GiftTransferModal,
|
giftTransferModal: GiftTransferModal,
|
||||||
chatRefundModal: ChatRefundModal,
|
chatRefundModal: ChatRefundModal,
|
||||||
isFrozenAccountModalOpen: FrozenAccountModal,
|
isFrozenAccountModalOpen: FrozenAccountModal,
|
||||||
|
deleteAccountModal: DeleteAccountModal,
|
||||||
};
|
};
|
||||||
const MODAL_KEYS = Object.keys(MODALS) as ModalKey[];
|
const MODAL_KEYS = Object.keys(MODALS) as ModalKey[];
|
||||||
const MODAL_ENTRIES = Object.entries(MODALS) as Entries<ModalRegistry>;
|
const MODAL_ENTRIES = Object.entries(MODALS) as Entries<ModalRegistry>;
|
||||||
|
|||||||
@ -0,0 +1,17 @@
|
|||||||
|
import type { FC } from '../../../lib/teact/teact';
|
||||||
|
import React from '../../../lib/teact/teact';
|
||||||
|
|
||||||
|
import type { OwnProps } from './DeleteAccountModal';
|
||||||
|
|
||||||
|
import { Bundles } from '../../../util/moduleLoader';
|
||||||
|
|
||||||
|
import useModuleLoader from '../../../hooks/useModuleLoader';
|
||||||
|
|
||||||
|
const DeleteAccountModalAsync: FC<OwnProps> = (props) => {
|
||||||
|
const { modal } = props;
|
||||||
|
const DeleteAccountModal = useModuleLoader(Bundles.Extra, 'DeleteAccountModal', !modal);
|
||||||
|
|
||||||
|
return DeleteAccountModal ? <DeleteAccountModal {...props} /> : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DeleteAccountModalAsync;
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
.root :global(.modal-dialog) {
|
||||||
|
max-width: 23.25rem;
|
||||||
|
}
|
||||||
117
src/components/modals/deleteAccount/DeleteAccountModal.tsx
Normal file
117
src/components/modals/deleteAccount/DeleteAccountModal.tsx
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
import React, { memo, useEffect, useMemo, useState } from '../../../lib/teact/teact';
|
||||||
|
import { getActions, withGlobal } from '../../../global';
|
||||||
|
|
||||||
|
import type { TabState } from '../../../global/types';
|
||||||
|
|
||||||
|
import { ACCOUNT_TTL_OPTIONS } from '../../../config.ts';
|
||||||
|
import { getClosestEntry } from '../../../util/getClosestEntry.ts';
|
||||||
|
|
||||||
|
import useLang from '../../../hooks/useLang';
|
||||||
|
import useLastCallback from '../../../hooks/useLastCallback';
|
||||||
|
|
||||||
|
import Button from '../../ui/Button';
|
||||||
|
import Modal from '../../ui/Modal';
|
||||||
|
import RadioGroup from '../../ui/RadioGroup.tsx';
|
||||||
|
|
||||||
|
import styles from './DeleteAccountModal.module.scss';
|
||||||
|
|
||||||
|
export type OwnProps = {
|
||||||
|
modal: TabState['deleteAccountModal'];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type StateProps = {
|
||||||
|
selfDestructAccountDays?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DAYS_PER_MONTH = 30;
|
||||||
|
|
||||||
|
const DeleteAccountModal = ({
|
||||||
|
modal,
|
||||||
|
selfDestructAccountDays,
|
||||||
|
}: OwnProps & StateProps) => {
|
||||||
|
const {
|
||||||
|
closeGiftCodeModal, closeDeleteAccountModal, setAccountTTL,
|
||||||
|
} = getActions();
|
||||||
|
const lang = useLang();
|
||||||
|
const isOpen = Boolean(modal);
|
||||||
|
|
||||||
|
const [selectedOption, setSelectedOption] = useState<string>();
|
||||||
|
|
||||||
|
const optionToDays = useLastCallback((value: string): number => {
|
||||||
|
return Number(value) * DAYS_PER_MONTH;
|
||||||
|
});
|
||||||
|
|
||||||
|
const initialSelectedOption = useMemo(() => {
|
||||||
|
if (!selfDestructAccountDays) return undefined;
|
||||||
|
return getClosestEntry(ACCOUNT_TTL_OPTIONS, selfDestructAccountDays / DAYS_PER_MONTH).toString();
|
||||||
|
}, [selfDestructAccountDays]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (initialSelectedOption) {
|
||||||
|
setSelectedOption(initialSelectedOption);
|
||||||
|
}
|
||||||
|
}, [initialSelectedOption]);
|
||||||
|
|
||||||
|
const options: { value: string; label: string }[] = useMemo(() => {
|
||||||
|
return ACCOUNT_TTL_OPTIONS.map((months) => ({
|
||||||
|
value: String(months),
|
||||||
|
label: lang('Months', { count: months }, { pluralValue: 1 }),
|
||||||
|
}));
|
||||||
|
}, [lang]);
|
||||||
|
|
||||||
|
const handleChange = useLastCallback((value: string) => {
|
||||||
|
setSelectedOption(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
const confirmHandler = useLastCallback(() => {
|
||||||
|
if (!selectedOption) return;
|
||||||
|
setAccountTTL({ days: optionToDays(selectedOption) });
|
||||||
|
});
|
||||||
|
|
||||||
|
const onCloseHandler = useLastCallback(() => {
|
||||||
|
closeDeleteAccountModal();
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
isOpen={isOpen}
|
||||||
|
title={lang('SelfDestructTitle')}
|
||||||
|
onClose={closeGiftCodeModal}
|
||||||
|
className={styles.root}
|
||||||
|
>
|
||||||
|
<p>{lang('SelfDestructSessionsDescription')}</p>
|
||||||
|
<RadioGroup
|
||||||
|
className="dialog-checkbox-group"
|
||||||
|
name="quick-reaction-settings"
|
||||||
|
options={options}
|
||||||
|
selected={selectedOption}
|
||||||
|
onChange={handleChange}
|
||||||
|
withIcon
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className="dialog-buttons mt-2"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
className="confirm-dialog-button"
|
||||||
|
isText
|
||||||
|
onClick={confirmHandler}
|
||||||
|
>
|
||||||
|
{lang('Save')}
|
||||||
|
</Button>
|
||||||
|
<Button color="danger" className="confirm-dialog-button" isText onClick={onCloseHandler}>
|
||||||
|
{lang('Cancel')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(withGlobal<OwnProps>(
|
||||||
|
(global, { modal }): StateProps => {
|
||||||
|
const { selfDestructAccountDays } = modal || {};
|
||||||
|
|
||||||
|
return {
|
||||||
|
selfDestructAccountDays,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
)(DeleteAccountModal));
|
||||||
@ -471,3 +471,5 @@ export const DEFAULT_GIFT_PROFILE_FILTER_OPTIONS: GiftProfileFilterOptions = {
|
|||||||
export const DEFAULT_RESALE_GIFTS_FILTER_OPTIONS: ResaleGiftsFilterOptions = {
|
export const DEFAULT_RESALE_GIFTS_FILTER_OPTIONS: ResaleGiftsFilterOptions = {
|
||||||
sortType: 'byDate',
|
sortType: 'byDate',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ACCOUNT_TTL_OPTIONS = [1, 3, 6, 12, 18, 24];
|
||||||
|
|||||||
@ -243,3 +243,37 @@ addActionHandler('terminateAllWebAuthorizations', async (global): Promise<void>
|
|||||||
};
|
};
|
||||||
setGlobal(global);
|
setGlobal(global);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addActionHandler('loadAccountDaysTtl', async (global, actions, payload): Promise<void> => {
|
||||||
|
const result = await callApi('fetchAccountTTL');
|
||||||
|
if (!result) return;
|
||||||
|
|
||||||
|
global = getGlobal();
|
||||||
|
global = {
|
||||||
|
...global,
|
||||||
|
settings: {
|
||||||
|
...global.settings,
|
||||||
|
accountDaysTtl: result.days,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
setGlobal(global);
|
||||||
|
});
|
||||||
|
|
||||||
|
addActionHandler('setAccountTTL', async (global, actions, payload): Promise<void> => {
|
||||||
|
const { days, tabId = getCurrentTabId() } = payload || {};
|
||||||
|
if (!days) return;
|
||||||
|
|
||||||
|
const result = await callApi('setAccountTTL', { days });
|
||||||
|
if (!result) return;
|
||||||
|
|
||||||
|
global = getGlobal();
|
||||||
|
global = {
|
||||||
|
...global,
|
||||||
|
settings: {
|
||||||
|
...global.settings,
|
||||||
|
accountDaysTtl: days,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
setGlobal(global);
|
||||||
|
actions.closeDeleteAccountModal({ tabId });
|
||||||
|
});
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import type { ActionReturnType } from '../../types';
|
import type { ActionReturnType } from '../../types';
|
||||||
|
|
||||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||||
import { addActionHandler } from '../..';
|
import { addActionHandler, setGlobal } from '../..';
|
||||||
import { updateTabState } from '../../reducers/tabs';
|
import { updateTabState } from '../../reducers/tabs';
|
||||||
|
import { selectTabState } from '../../selectors';
|
||||||
|
|
||||||
addActionHandler('openFrozenAccountModal', (global, actions, payload): ActionReturnType => {
|
addActionHandler('openFrozenAccountModal', (global, actions, payload): ActionReturnType => {
|
||||||
const { tabId = getCurrentTabId() } = payload || {};
|
const { tabId = getCurrentTabId() } = payload || {};
|
||||||
@ -19,3 +20,24 @@ addActionHandler('closeFrozenAccountModal', (global, actions, payload): ActionRe
|
|||||||
isFrozenAccountModalOpen: false,
|
isFrozenAccountModalOpen: false,
|
||||||
}, tabId);
|
}, tabId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addActionHandler('openDeleteAccountModal', (global, actions, payload): ActionReturnType => {
|
||||||
|
const { days, tabId = getCurrentTabId() } = payload || {};
|
||||||
|
if (!days) return;
|
||||||
|
|
||||||
|
global = updateTabState(global, {
|
||||||
|
...selectTabState(global, tabId),
|
||||||
|
deleteAccountModal: {
|
||||||
|
selfDestructAccountDays: days,
|
||||||
|
},
|
||||||
|
}, tabId);
|
||||||
|
setGlobal(global);
|
||||||
|
});
|
||||||
|
|
||||||
|
addActionHandler('closeDeleteAccountModal', (global, actions, payload): ActionReturnType => {
|
||||||
|
const { tabId = getCurrentTabId() } = payload || {};
|
||||||
|
|
||||||
|
return updateTabState(global, {
|
||||||
|
deleteAccountModal: undefined,
|
||||||
|
}, tabId);
|
||||||
|
});
|
||||||
|
|||||||
@ -281,6 +281,10 @@ function unsafeMigrateCache(cached: GlobalState, initialState: GlobalState) {
|
|||||||
cached.peers = initialState.peers;
|
cached.peers = initialState.peers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cached.settings.accountDaysTtl) {
|
||||||
|
cached.settings.accountDaysTtl = initialState.settings.accountDaysTtl;
|
||||||
|
}
|
||||||
|
|
||||||
if (!cached.cacheVersion) {
|
if (!cached.cacheVersion) {
|
||||||
cached.cacheVersion = initialState.cacheVersion;
|
cached.cacheVersion = initialState.cacheVersion;
|
||||||
// Reset because of the new action message structure
|
// Reset because of the new action message structure
|
||||||
@ -708,7 +712,7 @@ function omitLocalMedia(message: ApiMessage): ApiMessage {
|
|||||||
|
|
||||||
function reduceSettings<T extends GlobalState>(global: T): GlobalState['settings'] {
|
function reduceSettings<T extends GlobalState>(global: T): GlobalState['settings'] {
|
||||||
const {
|
const {
|
||||||
byKey, botVerificationShownPeerIds, notifyDefaults, lastPremiumBandwithNotificationDate, themes,
|
byKey, botVerificationShownPeerIds, notifyDefaults, lastPremiumBandwithNotificationDate, themes, accountDaysTtl,
|
||||||
} = global.settings;
|
} = global.settings;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -718,6 +722,7 @@ function reduceSettings<T extends GlobalState>(global: T): GlobalState['settings
|
|||||||
lastPremiumBandwithNotificationDate,
|
lastPremiumBandwithNotificationDate,
|
||||||
notifyDefaults,
|
notifyDefaults,
|
||||||
themes,
|
themes,
|
||||||
|
accountDaysTtl,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -309,6 +309,7 @@ export const INITIAL_GLOBAL_STATE: GlobalState = {
|
|||||||
patternColor: DARK_THEME_PATTERN_COLOR,
|
patternColor: DARK_THEME_PATTERN_COLOR,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
accountDaysTtl: 365,
|
||||||
},
|
},
|
||||||
|
|
||||||
serviceNotifications: [],
|
serviceNotifications: [],
|
||||||
|
|||||||
@ -1040,6 +1040,14 @@ export interface ActionPayloads {
|
|||||||
};
|
};
|
||||||
openFrozenAccountModal: WithTabId | undefined;
|
openFrozenAccountModal: WithTabId | undefined;
|
||||||
closeFrozenAccountModal: WithTabId | undefined;
|
closeFrozenAccountModal: WithTabId | undefined;
|
||||||
|
openDeleteAccountModal: {
|
||||||
|
days: number;
|
||||||
|
} & WithTabId | undefined;
|
||||||
|
closeDeleteAccountModal: WithTabId | undefined;
|
||||||
|
setAccountTTL: {
|
||||||
|
days: number;
|
||||||
|
} & WithTabId | undefined;
|
||||||
|
loadAccountDaysTtl: undefined;
|
||||||
|
|
||||||
// Chats
|
// Chats
|
||||||
loadPeerSettings: {
|
loadPeerSettings: {
|
||||||
|
|||||||
@ -415,6 +415,7 @@ export type GlobalState = {
|
|||||||
paidReactionPrivacy?: ApiPaidReactionPrivacyType;
|
paidReactionPrivacy?: ApiPaidReactionPrivacyType;
|
||||||
botVerificationShownPeerIds: string[];
|
botVerificationShownPeerIds: string[];
|
||||||
themes: Partial<Record<ThemeKey, IThemeSettings>>;
|
themes: Partial<Record<ThemeKey, IThemeSettings>>;
|
||||||
|
accountDaysTtl: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
push?: {
|
push?: {
|
||||||
|
|||||||
@ -741,6 +741,10 @@ export type TabState = {
|
|||||||
info: ApiCheckedGiftCode;
|
info: ApiCheckedGiftCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
deleteAccountModal?: {
|
||||||
|
selfDestructAccountDays: number;
|
||||||
|
};
|
||||||
|
|
||||||
paidReactionModal?: {
|
paidReactionModal?: {
|
||||||
chatId: string;
|
chatId: string;
|
||||||
messageId: number;
|
messageId: number;
|
||||||
|
|||||||
96
src/lib/gramjs/tl/api.d.ts
vendored
96
src/lib/gramjs/tl/api.d.ts
vendored
@ -3212,9 +3212,10 @@ namespace Api {
|
|||||||
resaleStars?: long;
|
resaleStars?: long;
|
||||||
canTransferAt?: int;
|
canTransferAt?: int;
|
||||||
canResellAt?: int;
|
canResellAt?: int;
|
||||||
CONSTRUCTOR_ID: 2900347777;
|
CONSTRUCTOR_ID: 775611918;
|
||||||
SUBCLASS_OF_ID: 2256589094;
|
SUBCLASS_OF_ID: 2256589094;
|
||||||
className: 'MessageActionStarGiftUnique';
|
className: 'MessageActionStarGiftUnique';
|
||||||
|
|
||||||
static fromReader(reader: Reader): MessageActionStarGiftUnique;
|
static fromReader(reader: Reader): MessageActionStarGiftUnique;
|
||||||
}
|
}
|
||||||
export class MessageActionPaidMessagesRefunded extends VirtualClass<{
|
export class MessageActionPaidMessagesRefunded extends VirtualClass<{
|
||||||
@ -3255,6 +3256,10 @@ namespace Api {
|
|||||||
callId: long;
|
callId: long;
|
||||||
duration?: int;
|
duration?: int;
|
||||||
otherParticipants?: Api.TypePeer[];
|
otherParticipants?: Api.TypePeer[];
|
||||||
|
CONSTRUCTOR_ID: 805187450;
|
||||||
|
SUBCLASS_OF_ID: 2256589094;
|
||||||
|
className: 'MessageActionConferenceCall';
|
||||||
|
|
||||||
static fromReader(reader: Reader): MessageActionConferenceCall;
|
static fromReader(reader: Reader): MessageActionConferenceCall;
|
||||||
}
|
}
|
||||||
export class Dialog extends VirtualClass<{
|
export class Dialog extends VirtualClass<{
|
||||||
@ -5951,6 +5956,10 @@ namespace Api {
|
|||||||
subChainId: int;
|
subChainId: int;
|
||||||
blocks: bytes[];
|
blocks: bytes[];
|
||||||
nextOffset: int;
|
nextOffset: int;
|
||||||
|
CONSTRUCTOR_ID: 2759272591;
|
||||||
|
SUBCLASS_OF_ID: 2676568142;
|
||||||
|
className: 'UpdateGroupCallChainBlocks';
|
||||||
|
|
||||||
static fromReader(reader: Reader): UpdateGroupCallChainBlocks;
|
static fromReader(reader: Reader): UpdateGroupCallChainBlocks;
|
||||||
}
|
}
|
||||||
export class UpdatesTooLong extends VirtualClass<void> {
|
export class UpdatesTooLong extends VirtualClass<void> {
|
||||||
@ -9904,6 +9913,10 @@ namespace Api {
|
|||||||
slug: string;
|
slug: string;
|
||||||
}> {
|
}> {
|
||||||
slug: string;
|
slug: string;
|
||||||
|
CONSTRUCTOR_ID: 2679894519;
|
||||||
|
SUBCLASS_OF_ID: 3634081085;
|
||||||
|
className: 'PhoneCallDiscardReasonMigrateConferenceCall';
|
||||||
|
|
||||||
static fromReader(reader: Reader): PhoneCallDiscardReasonMigrateConferenceCall;
|
static fromReader(reader: Reader): PhoneCallDiscardReasonMigrateConferenceCall;
|
||||||
}
|
}
|
||||||
export class DataJSON extends VirtualClass<{
|
export class DataJSON extends VirtualClass<{
|
||||||
@ -10250,8 +10263,7 @@ namespace Api {
|
|||||||
participantId: long;
|
participantId: long;
|
||||||
protocol: Api.TypePhoneCallProtocol;
|
protocol: Api.TypePhoneCallProtocol;
|
||||||
receiveDate?: int;
|
receiveDate?: int;
|
||||||
conferenceCall?: Api.TypeInputGroupCall;
|
CONSTRUCTOR_ID: 3307368215;
|
||||||
CONSTRUCTOR_ID: 4006881368;
|
|
||||||
SUBCLASS_OF_ID: 3296664529;
|
SUBCLASS_OF_ID: 3296664529;
|
||||||
className: 'PhoneCallWaiting';
|
className: 'PhoneCallWaiting';
|
||||||
|
|
||||||
@ -10277,8 +10289,7 @@ namespace Api {
|
|||||||
participantId: long;
|
participantId: long;
|
||||||
gAHash: bytes;
|
gAHash: bytes;
|
||||||
protocol: Api.TypePhoneCallProtocol;
|
protocol: Api.TypePhoneCallProtocol;
|
||||||
conferenceCall?: Api.TypeInputGroupCall;
|
CONSTRUCTOR_ID: 347139340;
|
||||||
CONSTRUCTOR_ID: 1161174115;
|
|
||||||
SUBCLASS_OF_ID: 3296664529;
|
SUBCLASS_OF_ID: 3296664529;
|
||||||
className: 'PhoneCallRequested';
|
className: 'PhoneCallRequested';
|
||||||
|
|
||||||
@ -10304,8 +10315,7 @@ namespace Api {
|
|||||||
participantId: long;
|
participantId: long;
|
||||||
gB: bytes;
|
gB: bytes;
|
||||||
protocol: Api.TypePhoneCallProtocol;
|
protocol: Api.TypePhoneCallProtocol;
|
||||||
conferenceCall?: Api.TypeInputGroupCall;
|
CONSTRUCTOR_ID: 912311057;
|
||||||
CONSTRUCTOR_ID: 587035009;
|
|
||||||
SUBCLASS_OF_ID: 3296664529;
|
SUBCLASS_OF_ID: 3296664529;
|
||||||
className: 'PhoneCallAccepted';
|
className: 'PhoneCallAccepted';
|
||||||
|
|
||||||
@ -10343,8 +10353,7 @@ namespace Api {
|
|||||||
connections: Api.TypePhoneConnection[];
|
connections: Api.TypePhoneConnection[];
|
||||||
startDate: int;
|
startDate: int;
|
||||||
customParameters?: Api.TypeDataJSON;
|
customParameters?: Api.TypeDataJSON;
|
||||||
conferenceCall?: Api.TypeInputGroupCall;
|
CONSTRUCTOR_ID: 810769141;
|
||||||
CONSTRUCTOR_ID: 1000707084;
|
|
||||||
SUBCLASS_OF_ID: 3296664529;
|
SUBCLASS_OF_ID: 3296664529;
|
||||||
className: 'PhoneCall';
|
className: 'PhoneCall';
|
||||||
|
|
||||||
@ -10366,8 +10375,7 @@ namespace Api {
|
|||||||
id: long;
|
id: long;
|
||||||
reason?: Api.TypePhoneCallDiscardReason;
|
reason?: Api.TypePhoneCallDiscardReason;
|
||||||
duration?: int;
|
duration?: int;
|
||||||
conferenceCall?: Api.TypeInputGroupCall;
|
CONSTRUCTOR_ID: 1355435489;
|
||||||
CONSTRUCTOR_ID: 4191311107;
|
|
||||||
SUBCLASS_OF_ID: 3296664529;
|
SUBCLASS_OF_ID: 3296664529;
|
||||||
className: 'PhoneCallDiscarded';
|
className: 'PhoneCallDiscarded';
|
||||||
|
|
||||||
@ -11111,6 +11119,10 @@ namespace Api {
|
|||||||
newValue: Bool;
|
newValue: Bool;
|
||||||
}> {
|
}> {
|
||||||
newValue: Bool;
|
newValue: Bool;
|
||||||
|
CONSTRUCTOR_ID: 3306682238;
|
||||||
|
SUBCLASS_OF_ID: 2998503411;
|
||||||
|
className: 'ChannelAdminLogEventActionToggleAutotranslation';
|
||||||
|
|
||||||
static fromReader(reader: Reader): ChannelAdminLogEventActionToggleAutotranslation;
|
static fromReader(reader: Reader): ChannelAdminLogEventActionToggleAutotranslation;
|
||||||
}
|
}
|
||||||
export class ChannelAdminLogEvent extends VirtualClass<{
|
export class ChannelAdminLogEvent extends VirtualClass<{
|
||||||
@ -13281,11 +13293,11 @@ namespace Api {
|
|||||||
unmutedVideoCount?: int;
|
unmutedVideoCount?: int;
|
||||||
unmutedVideoLimit: int;
|
unmutedVideoLimit: int;
|
||||||
version: int;
|
version: int;
|
||||||
conferenceFromCall?: long;
|
|
||||||
inviteLink?: string;
|
inviteLink?: string;
|
||||||
CONSTRUCTOR_ID: 3455636451;
|
CONSTRUCTOR_ID: 1429932961;
|
||||||
SUBCLASS_OF_ID: 548729632;
|
SUBCLASS_OF_ID: 548729632;
|
||||||
className: 'GroupCall';
|
className: 'GroupCall';
|
||||||
|
|
||||||
static fromReader(reader: Reader): GroupCall;
|
static fromReader(reader: Reader): GroupCall;
|
||||||
}
|
}
|
||||||
export class InputGroupCall extends VirtualClass<{
|
export class InputGroupCall extends VirtualClass<{
|
||||||
@ -13304,12 +13316,20 @@ namespace Api {
|
|||||||
slug: string;
|
slug: string;
|
||||||
}> {
|
}> {
|
||||||
slug: string;
|
slug: string;
|
||||||
|
CONSTRUCTOR_ID: 4261839423;
|
||||||
|
SUBCLASS_OF_ID: 1482758833;
|
||||||
|
className: 'InputGroupCallSlug';
|
||||||
|
|
||||||
static fromReader(reader: Reader): InputGroupCallSlug;
|
static fromReader(reader: Reader): InputGroupCallSlug;
|
||||||
}
|
}
|
||||||
export class InputGroupCallInviteMessage extends VirtualClass<{
|
export class InputGroupCallInviteMessage extends VirtualClass<{
|
||||||
msgId: int;
|
msgId: int;
|
||||||
}> {
|
}> {
|
||||||
msgId: int;
|
msgId: int;
|
||||||
|
CONSTRUCTOR_ID: 2349883455;
|
||||||
|
SUBCLASS_OF_ID: 1482758833;
|
||||||
|
className: 'InputGroupCallInviteMessage';
|
||||||
|
|
||||||
static fromReader(reader: Reader): InputGroupCallInviteMessage;
|
static fromReader(reader: Reader): InputGroupCallInviteMessage;
|
||||||
}
|
}
|
||||||
export class GroupCallParticipant extends VirtualClass<{
|
export class GroupCallParticipant extends VirtualClass<{
|
||||||
@ -14052,6 +14072,10 @@ namespace Api {
|
|||||||
}> {
|
}> {
|
||||||
slug: string;
|
slug: string;
|
||||||
toId: Api.TypeInputPeer;
|
toId: Api.TypeInputPeer;
|
||||||
|
CONSTRUCTOR_ID: 1674298252;
|
||||||
|
SUBCLASS_OF_ID: 1919851518;
|
||||||
|
className: 'InputInvoiceStarGiftResale';
|
||||||
|
|
||||||
static fromReader(reader: Reader): InputInvoiceStarGiftResale;
|
static fromReader(reader: Reader): InputInvoiceStarGiftResale;
|
||||||
}
|
}
|
||||||
export class InputStorePaymentPremiumSubscription extends VirtualClass<{
|
export class InputStorePaymentPremiumSubscription extends VirtualClass<{
|
||||||
@ -16601,9 +16625,10 @@ namespace Api {
|
|||||||
upgradeStars?: long;
|
upgradeStars?: long;
|
||||||
resellMinStars?: long;
|
resellMinStars?: long;
|
||||||
title?: string;
|
title?: string;
|
||||||
CONSTRUCTOR_ID: 46953416;
|
CONSTRUCTOR_ID: 3324693032;
|
||||||
SUBCLASS_OF_ID: 3273414923;
|
SUBCLASS_OF_ID: 3273414923;
|
||||||
className: 'StarGift';
|
className: 'StarGift';
|
||||||
|
|
||||||
static fromReader(reader: Reader): StarGift;
|
static fromReader(reader: Reader): StarGift;
|
||||||
}
|
}
|
||||||
export class StarGiftUnique extends VirtualClass<{
|
export class StarGiftUnique extends VirtualClass<{
|
||||||
@ -16634,9 +16659,10 @@ namespace Api {
|
|||||||
availabilityTotal: int;
|
availabilityTotal: int;
|
||||||
giftAddress?: string;
|
giftAddress?: string;
|
||||||
resellStars?: long;
|
resellStars?: long;
|
||||||
CONSTRUCTOR_ID: 1549979985;
|
CONSTRUCTOR_ID: 1678891913;
|
||||||
SUBCLASS_OF_ID: 3273414923;
|
SUBCLASS_OF_ID: 3273414923;
|
||||||
className: 'StarGiftUnique';
|
className: 'StarGiftUnique';
|
||||||
|
|
||||||
static fromReader(reader: Reader): StarGiftUnique;
|
static fromReader(reader: Reader): StarGiftUnique;
|
||||||
}
|
}
|
||||||
export class MessageReportOption extends VirtualClass<{
|
export class MessageReportOption extends VirtualClass<{
|
||||||
@ -16838,7 +16864,7 @@ namespace Api {
|
|||||||
patternColor: int;
|
patternColor: int;
|
||||||
textColor: int;
|
textColor: int;
|
||||||
rarityPermille: int;
|
rarityPermille: int;
|
||||||
CONSTRUCTOR_ID: 2485589858;
|
CONSTRUCTOR_ID: 3644687772;
|
||||||
SUBCLASS_OF_ID: 2276819400;
|
SUBCLASS_OF_ID: 2276819400;
|
||||||
className: 'StarGiftAttributeBackdrop';
|
className: 'StarGiftAttributeBackdrop';
|
||||||
|
|
||||||
@ -16900,9 +16926,10 @@ namespace Api {
|
|||||||
transferStars?: long;
|
transferStars?: long;
|
||||||
canTransferAt?: int;
|
canTransferAt?: int;
|
||||||
canResellAt?: int;
|
canResellAt?: int;
|
||||||
CONSTRUCTOR_ID: 1616305061;
|
CONSTRUCTOR_ID: 3755607193;
|
||||||
SUBCLASS_OF_ID: 2385198100;
|
SUBCLASS_OF_ID: 2385198100;
|
||||||
className: 'SavedStarGift';
|
className: 'SavedStarGift';
|
||||||
|
|
||||||
static fromReader(reader: Reader): SavedStarGift;
|
static fromReader(reader: Reader): SavedStarGift;
|
||||||
}
|
}
|
||||||
export class InputSavedStarGiftUser extends VirtualClass<{
|
export class InputSavedStarGiftUser extends VirtualClass<{
|
||||||
@ -16931,6 +16958,10 @@ namespace Api {
|
|||||||
slug: string;
|
slug: string;
|
||||||
}> {
|
}> {
|
||||||
slug: string;
|
slug: string;
|
||||||
|
CONSTRUCTOR_ID: 545636920;
|
||||||
|
SUBCLASS_OF_ID: 2406848942;
|
||||||
|
className: 'InputSavedStarGiftSlug';
|
||||||
|
|
||||||
static fromReader(reader: Reader): InputSavedStarGiftSlug;
|
static fromReader(reader: Reader): InputSavedStarGiftSlug;
|
||||||
}
|
}
|
||||||
export class PaidReactionPrivacyDefault extends VirtualClass<void> {
|
export class PaidReactionPrivacyDefault extends VirtualClass<void> {
|
||||||
@ -17059,18 +17090,30 @@ namespace Api {
|
|||||||
documentId: long;
|
documentId: long;
|
||||||
}> {
|
}> {
|
||||||
documentId: long;
|
documentId: long;
|
||||||
|
CONSTRUCTOR_ID: 1219145276;
|
||||||
|
SUBCLASS_OF_ID: 3005295287;
|
||||||
|
className: 'StarGiftAttributeIdModel';
|
||||||
|
|
||||||
static fromReader(reader: Reader): StarGiftAttributeIdModel;
|
static fromReader(reader: Reader): StarGiftAttributeIdModel;
|
||||||
}
|
}
|
||||||
export class StarGiftAttributeIdPattern extends VirtualClass<{
|
export class StarGiftAttributeIdPattern extends VirtualClass<{
|
||||||
documentId: long;
|
documentId: long;
|
||||||
}> {
|
}> {
|
||||||
documentId: long;
|
documentId: long;
|
||||||
|
CONSTRUCTOR_ID: 1242965043;
|
||||||
|
SUBCLASS_OF_ID: 3005295287;
|
||||||
|
className: 'StarGiftAttributeIdPattern';
|
||||||
|
|
||||||
static fromReader(reader: Reader): StarGiftAttributeIdPattern;
|
static fromReader(reader: Reader): StarGiftAttributeIdPattern;
|
||||||
}
|
}
|
||||||
export class StarGiftAttributeIdBackdrop extends VirtualClass<{
|
export class StarGiftAttributeIdBackdrop extends VirtualClass<{
|
||||||
backdropId: int;
|
backdropId: int;
|
||||||
}> {
|
}> {
|
||||||
backdropId: int;
|
backdropId: int;
|
||||||
|
CONSTRUCTOR_ID: 520210263;
|
||||||
|
SUBCLASS_OF_ID: 3005295287;
|
||||||
|
className: 'StarGiftAttributeIdBackdrop';
|
||||||
|
|
||||||
static fromReader(reader: Reader): StarGiftAttributeIdBackdrop;
|
static fromReader(reader: Reader): StarGiftAttributeIdBackdrop;
|
||||||
}
|
}
|
||||||
export class StarGiftAttributeCounter extends VirtualClass<{
|
export class StarGiftAttributeCounter extends VirtualClass<{
|
||||||
@ -17079,6 +17122,10 @@ namespace Api {
|
|||||||
}> {
|
}> {
|
||||||
attribute: Api.TypeStarGiftAttributeId;
|
attribute: Api.TypeStarGiftAttributeId;
|
||||||
count: int;
|
count: int;
|
||||||
|
CONSTRUCTOR_ID: 783398488;
|
||||||
|
SUBCLASS_OF_ID: 2351477395;
|
||||||
|
className: 'StarGiftAttributeCounter';
|
||||||
|
|
||||||
static fromReader(reader: Reader): StarGiftAttributeCounter;
|
static fromReader(reader: Reader): StarGiftAttributeCounter;
|
||||||
}
|
}
|
||||||
export class PendingSuggestion extends VirtualClass<{
|
export class PendingSuggestion extends VirtualClass<{
|
||||||
@ -17091,6 +17138,10 @@ namespace Api {
|
|||||||
title: Api.TypeTextWithEntities;
|
title: Api.TypeTextWithEntities;
|
||||||
description: Api.TypeTextWithEntities;
|
description: Api.TypeTextWithEntities;
|
||||||
url: string;
|
url: string;
|
||||||
|
CONSTRUCTOR_ID: 3890753042;
|
||||||
|
SUBCLASS_OF_ID: 3126949031;
|
||||||
|
className: 'PendingSuggestion';
|
||||||
|
|
||||||
static fromReader(reader: Reader): PendingSuggestion;
|
static fromReader(reader: Reader): PendingSuggestion;
|
||||||
}
|
}
|
||||||
export class ResPQ extends VirtualClass<{
|
export class ResPQ extends VirtualClass<{
|
||||||
@ -19899,9 +19950,10 @@ namespace Api {
|
|||||||
customPendingSuggestion?: Api.TypePendingSuggestion;
|
customPendingSuggestion?: Api.TypePendingSuggestion;
|
||||||
chats: Api.TypeChat[];
|
chats: Api.TypeChat[];
|
||||||
users: Api.TypeUser[];
|
users: Api.TypeUser[];
|
||||||
CONSTRUCTOR_ID: 2352576831;
|
CONSTRUCTOR_ID: 145021050;
|
||||||
SUBCLASS_OF_ID: 2639877442;
|
SUBCLASS_OF_ID: 2639877442;
|
||||||
className: 'PromoData';
|
className: 'PromoData';
|
||||||
|
|
||||||
static fromReader(reader: Reader): PromoData;
|
static fromReader(reader: Reader): PromoData;
|
||||||
}
|
}
|
||||||
export class CountryCode extends VirtualClass<{
|
export class CountryCode extends VirtualClass<{
|
||||||
@ -21081,6 +21133,10 @@ namespace Api {
|
|||||||
chats: Api.TypeChat[];
|
chats: Api.TypeChat[];
|
||||||
counters?: Api.TypeStarGiftAttributeCounter[];
|
counters?: Api.TypeStarGiftAttributeCounter[];
|
||||||
users: Api.TypeUser[];
|
users: Api.TypeUser[];
|
||||||
|
CONSTRUCTOR_ID: 2491028191;
|
||||||
|
SUBCLASS_OF_ID: 3000743907;
|
||||||
|
className: 'ResaleStarGifts';
|
||||||
|
|
||||||
static fromReader(reader: Reader): ResaleStarGifts;
|
static fromReader(reader: Reader): ResaleStarGifts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -21696,6 +21752,10 @@ namespace Api {
|
|||||||
countRemains: int;
|
countRemains: int;
|
||||||
}> {
|
}> {
|
||||||
countRemains: int;
|
countRemains: int;
|
||||||
|
CONSTRUCTOR_ID: 3280453710;
|
||||||
|
SUBCLASS_OF_ID: 3411255960;
|
||||||
|
className: 'CanSendStoryCount';
|
||||||
|
|
||||||
static fromReader(reader: Reader): CanSendStoryCount;
|
static fromReader(reader: Reader): CanSendStoryCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1466,6 +1466,8 @@ account.checkUsername#2714d86c username:string = Bool;
|
|||||||
account.updateUsername#3e0bdd7c username:string = User;
|
account.updateUsername#3e0bdd7c username:string = User;
|
||||||
account.getPrivacy#dadbc950 key:InputPrivacyKey = account.PrivacyRules;
|
account.getPrivacy#dadbc950 key:InputPrivacyKey = account.PrivacyRules;
|
||||||
account.setPrivacy#c9f81ce8 key:InputPrivacyKey rules:Vector<InputPrivacyRule> = account.PrivacyRules;
|
account.setPrivacy#c9f81ce8 key:InputPrivacyKey rules:Vector<InputPrivacyRule> = account.PrivacyRules;
|
||||||
|
account.getAccountTTL#8fc711d = AccountDaysTTL;
|
||||||
|
account.setAccountTTL#2442485e ttl:AccountDaysTTL = Bool;
|
||||||
account.getAuthorizations#e320c158 = account.Authorizations;
|
account.getAuthorizations#e320c158 = account.Authorizations;
|
||||||
account.resetAuthorization#df77f3bc hash:long = Bool;
|
account.resetAuthorization#df77f3bc hash:long = Bool;
|
||||||
account.getPassword#548a30f5 = account.Password;
|
account.getPassword#548a30f5 = account.Password;
|
||||||
|
|||||||
@ -63,6 +63,8 @@
|
|||||||
"account.getCollectibleEmojiStatuses",
|
"account.getCollectibleEmojiStatuses",
|
||||||
"account.addNoPaidMessagesException",
|
"account.addNoPaidMessagesException",
|
||||||
"account.getPaidMessagesRevenue",
|
"account.getPaidMessagesRevenue",
|
||||||
|
"account.getAccountTTL",
|
||||||
|
"account.setAccountTTL",
|
||||||
"users.getUsers",
|
"users.getUsers",
|
||||||
"users.getFullUser",
|
"users.getFullUser",
|
||||||
"contacts.getContacts",
|
"contacts.getContacts",
|
||||||
|
|||||||
4
src/types/language.d.ts
vendored
4
src/types/language.d.ts
vendored
@ -1272,6 +1272,10 @@ export interface LangPair {
|
|||||||
'CloseMiniApps': undefined;
|
'CloseMiniApps': undefined;
|
||||||
'DoNotAskAgain': undefined;
|
'DoNotAskAgain': undefined;
|
||||||
'PaymentInfoDone': undefined;
|
'PaymentInfoDone': undefined;
|
||||||
|
'DeleteMyAccount': undefined;
|
||||||
|
'DeleteAccountIfAwayFor': undefined;
|
||||||
|
'SelfDestructTitle': undefined;
|
||||||
|
'SelfDestructSessionsDescription': undefined;
|
||||||
'VideoConversionTitle': undefined;
|
'VideoConversionTitle': undefined;
|
||||||
'VideoConversionText': undefined;
|
'VideoConversionText': undefined;
|
||||||
'VideoConversionDone': undefined;
|
'VideoConversionDone': undefined;
|
||||||
|
|||||||
5
src/util/getClosestEntry.ts
Normal file
5
src/util/getClosestEntry.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export function getClosestEntry(arr: number[], value: number): number {
|
||||||
|
return arr.reduce((prev, curr) => {
|
||||||
|
return Math.abs(curr - value) < Math.abs(prev - value) ? curr : prev;
|
||||||
|
});
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user