ChatList: Display unconfirmed sessions (#3887)

This commit is contained in:
Alexander Zinchuk 2023-10-10 13:35:14 +02:00
parent a21019c340
commit 0d843112fa
17 changed files with 185 additions and 19 deletions

View File

@ -44,6 +44,7 @@ export interface GramJsAppConfig extends LimitsConfig {
default_emoji_statuses_stickerset_id: string; default_emoji_statuses_stickerset_id: string;
hidden_members_group_size_min: number; hidden_members_group_size_min: number;
autoarchive_setting_available: boolean; autoarchive_setting_available: boolean;
authorization_autoconfirm_period: number;
// Forums // Forums
topics_pinned_limit: number; topics_pinned_limit: number;
// Stories // Stories

View File

@ -43,6 +43,7 @@ export function buildApiSession(session: GramJs.Authorization): ApiSession {
hash: String(session.hash), hash: String(session.hash),
areCallsEnabled: !session.callRequestsDisabled, areCallsEnabled: !session.callRequestsDisabled,
areSecretChatsEnabled: !session.encryptedRequestsDisabled, areSecretChatsEnabled: !session.encryptedRequestsDisabled,
isUnconfirmed: session.unconfirmed,
...pick(session, [ ...pick(session, [
'deviceModel', 'platform', 'systemVersion', 'appName', 'appVersion', 'dateCreated', 'dateActive', 'deviceModel', 'platform', 'systemVersion', 'appName', 'appVersion', 'dateCreated', 'dateActive',
'ip', 'country', 'region', 'ip', 'country', 'region',

View File

@ -46,14 +46,15 @@ export async function reportProfilePhoto({
} }
export async function changeSessionSettings({ export async function changeSessionSettings({
hash, areCallsEnabled, areSecretChatsEnabled, hash, areCallsEnabled, areSecretChatsEnabled, isConfirmed,
}: { }: {
hash: string; areCallsEnabled?: boolean; areSecretChatsEnabled?: boolean; hash: string; areCallsEnabled?: boolean; areSecretChatsEnabled?: boolean; isConfirmed?: boolean;
}) { }) {
const result = await invokeRequest(new GramJs.account.ChangeAuthorizationSettings({ const result = await invokeRequest(new GramJs.account.ChangeAuthorizationSettings({
hash: BigInt(hash), hash: BigInt(hash),
...(areCallsEnabled !== undefined ? { callRequestsDisabled: !areCallsEnabled } : undefined), ...(areCallsEnabled !== undefined ? { callRequestsDisabled: !areCallsEnabled } : undefined),
...(areSecretChatsEnabled !== undefined ? { encryptedRequestsDisabled: !areSecretChatsEnabled } : undefined), ...(areSecretChatsEnabled !== undefined ? { encryptedRequestsDisabled: !areSecretChatsEnabled } : undefined),
...(isConfirmed && { confirmed: isConfirmed }),
})); }));
return result; return result;

View File

@ -1108,6 +1108,15 @@ export function updater(update: Update) {
onUpdate({ onUpdate({
'@type': 'updateAttachMenuBots', '@type': 'updateAttachMenuBots',
}); });
} else if (update instanceof GramJs.UpdateNewAuthorization) {
onUpdate({
'@type': 'updateNewAuthorization',
hash: update.hash.toString(),
date: update.date,
device: update.device,
location: update.location,
isUnconfirmed: update.unconfirmed,
});
} else if (DEBUG) { } else if (DEBUG) {
const params = typeof update === 'object' && 'className' in update ? update.className : update; const params = typeof update === 'object' && 'className' in update ? update.className : update;
log('UNEXPECTED UPDATE', params); log('UNEXPECTED UPDATE', params);

View File

@ -76,6 +76,7 @@ export interface ApiSession {
region: string; region: string;
areCallsEnabled: boolean; areCallsEnabled: boolean;
areSecretChatsEnabled: boolean; areSecretChatsEnabled: boolean;
isUnconfirmed?: true;
} }
export interface ApiWebSession { export interface ApiWebSession {

View File

@ -665,6 +665,15 @@ export type ApiUpdateAttachMenuBots = {
'@type': 'updateAttachMenuBots'; '@type': 'updateAttachMenuBots';
}; };
export type ApiUpdateNewAuthorization = {
'@type': 'updateNewAuthorization';
hash: string;
isUnconfirmed?: true;
date?: number;
device?: string;
location?: string;
};
export type ApiUpdate = ( export type ApiUpdate = (
ApiUpdateReady | ApiUpdateSession | ApiUpdateWebAuthTokenFailed | ApiUpdateRequestUserUpdate | ApiUpdateReady | ApiUpdateSession | ApiUpdateWebAuthTokenFailed | ApiUpdateRequestUserUpdate |
ApiUpdateAuthorizationState | ApiUpdateAuthorizationError | ApiUpdateConnectionState | ApiUpdateCurrentUser | ApiUpdateAuthorizationState | ApiUpdateAuthorizationError | ApiUpdateConnectionState | ApiUpdateCurrentUser |
@ -693,7 +702,7 @@ export type ApiUpdate = (
ApiUpdatePinnedTopicsOrder | ApiUpdateTopic | ApiUpdateTopics | ApiUpdateRecentEmojiStatuses | ApiUpdatePinnedTopicsOrder | ApiUpdateTopic | ApiUpdateTopics | ApiUpdateRecentEmojiStatuses |
ApiUpdateRecentReactions | ApiUpdateStory | ApiUpdateReadStories | ApiUpdateDeleteStory | ApiUpdateSentStoryReaction | ApiUpdateRecentReactions | ApiUpdateStory | ApiUpdateReadStories | ApiUpdateDeleteStory | ApiUpdateSentStoryReaction |
ApiRequestReconnectApi | ApiRequestSync | ApiUpdateFetchingDifference | ApiUpdateChannelMessages | ApiRequestReconnectApi | ApiRequestSync | ApiUpdateFetchingDifference | ApiUpdateChannelMessages |
ApiUpdateStealthMode | ApiUpdateAttachMenuBots ApiUpdateStealthMode | ApiUpdateAttachMenuBots | ApiUpdateNewAuthorization
); );
export type OnApiUpdate = (update: ApiUpdate) => void; export type OnApiUpdate = (update: ApiUpdate) => void;

View File

@ -4,7 +4,7 @@ import React, {
} from '../../../lib/teact/teact'; } from '../../../lib/teact/teact';
import { getActions, getGlobal, withGlobal } from '../../../global'; import { getActions, getGlobal, withGlobal } from '../../../global';
import type { ApiChatFolder, ApiChatlistExportedInvite } from '../../../api/types'; import type { ApiChatFolder, ApiChatlistExportedInvite, ApiSession } from '../../../api/types';
import type { GlobalState } from '../../../global/types'; import type { GlobalState } from '../../../global/types';
import type { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer'; import type { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer';
import type { LeftColumnContent, SettingsScreens } from '../../../types'; import type { LeftColumnContent, SettingsScreens } from '../../../types';
@ -53,6 +53,7 @@ type StateProps = {
hasArchivedStories?: boolean; hasArchivedStories?: boolean;
archiveSettings: GlobalState['archiveSettings']; archiveSettings: GlobalState['archiveSettings'];
isStoryRibbonShown?: boolean; isStoryRibbonShown?: boolean;
sessions?: Record<string, ApiSession>;
}; };
const SAVED_MESSAGES_HOTKEY = '0'; const SAVED_MESSAGES_HOTKEY = '0';
@ -77,6 +78,7 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
hasArchivedStories, hasArchivedStories,
archiveSettings, archiveSettings,
isStoryRibbonShown, isStoryRibbonShown,
sessions,
}) => { }) => {
const { const {
loadChatFolders, loadChatFolders,
@ -299,6 +301,7 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
onLeftColumnContentChange={onLeftColumnContentChange} onLeftColumnContentChange={onLeftColumnContentChange}
canDisplayArchive={(hasArchivedChats || hasArchivedStories) && !archiveSettings.isHidden} canDisplayArchive={(hasArchivedChats || hasArchivedStories) && !archiveSettings.isHidden}
archiveSettings={archiveSettings} archiveSettings={archiveSettings}
sessions={sessions}
/> />
); );
} }
@ -356,6 +359,9 @@ export default memo(withGlobal<OwnProps>(
archived: archivedStories, archived: archivedStories,
}, },
}, },
activeSessions: {
byHash: sessions,
},
currentUserId, currentUserId,
archiveSettings, archiveSettings,
} = global; } = global;
@ -376,6 +382,7 @@ export default memo(withGlobal<OwnProps>(
maxChatLists: selectCurrentLimit(global, 'chatlistJoined'), maxChatLists: selectCurrentLimit(global, 'chatlistJoined'),
archiveSettings, archiveSettings,
isStoryRibbonShown, isStoryRibbonShown,
sessions,
}; };
}, },
)(ChatFolders)); )(ChatFolders));

View File

@ -1,9 +1,10 @@
import type { FC } from '../../../lib/teact/teact'; import type { FC } from '../../../lib/teact/teact';
import React, { import React, {
memo, useEffect, useRef, memo, useEffect, useMemo, useRef, useState,
} from '../../../lib/teact/teact'; } from '../../../lib/teact/teact';
import { getActions } from '../../../global'; import { getActions } from '../../../global';
import type { ApiSession } from '../../../api/types';
import type { GlobalState } from '../../../global/types'; import type { GlobalState } from '../../../global/types';
import type { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer'; import type { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer';
import type { SettingsScreens } from '../../../types'; import type { SettingsScreens } from '../../../types';
@ -15,9 +16,11 @@ import {
ARCHIVED_FOLDER_ID, ARCHIVED_FOLDER_ID,
CHAT_HEIGHT_PX, CHAT_HEIGHT_PX,
CHAT_LIST_SLICE, CHAT_LIST_SLICE,
FRESH_AUTH_PERIOD,
} from '../../../config'; } from '../../../config';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
import { getOrderKey, getPinnedChatsCount } from '../../../util/folderManager'; import { getOrderKey, getPinnedChatsCount } from '../../../util/folderManager';
import { getServerTime } from '../../../util/serverTime';
import { IS_APP, IS_MAC_OS } from '../../../util/windowEnvironment'; import { IS_APP, IS_MAC_OS } from '../../../util/windowEnvironment';
import useUserStoriesPolling from '../../../hooks/polling/useUserStoriesPolling'; import useUserStoriesPolling from '../../../hooks/polling/useUserStoriesPolling';
@ -35,6 +38,7 @@ import Loading from '../../ui/Loading';
import Archive from './Archive'; import Archive from './Archive';
import Chat from './Chat'; import Chat from './Chat';
import EmptyFolder from './EmptyFolder'; import EmptyFolder from './EmptyFolder';
import UnconfirmedSession from './UnconfirmedSession';
type OwnProps = { type OwnProps = {
folderType: 'all' | 'archived' | 'folder'; folderType: 'all' | 'archived' | 'folder';
@ -43,7 +47,7 @@ type OwnProps = {
canDisplayArchive?: boolean; canDisplayArchive?: boolean;
archiveSettings: GlobalState['archiveSettings']; archiveSettings: GlobalState['archiveSettings'];
isForumPanelOpen?: boolean; isForumPanelOpen?: boolean;
className?: string; sessions?: Record<string, ApiSession>;
foldersDispatch: FolderEditDispatch; foldersDispatch: FolderEditDispatch;
onSettingsScreenSelect: (screen: SettingsScreens) => void; onSettingsScreenSelect: (screen: SettingsScreens) => void;
onLeftColumnContentChange: (content: LeftColumnContent) => void; onLeftColumnContentChange: (content: LeftColumnContent) => void;
@ -60,6 +64,7 @@ const ChatList: FC<OwnProps> = ({
isForumPanelOpen, isForumPanelOpen,
canDisplayArchive, canDisplayArchive,
archiveSettings, archiveSettings,
sessions,
foldersDispatch, foldersDispatch,
onSettingsScreenSelect, onSettingsScreenSelect,
onLeftColumnContentChange, onLeftColumnContentChange,
@ -73,13 +78,15 @@ const ChatList: FC<OwnProps> = ({
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
const shouldIgnoreDragRef = useRef(false); const shouldIgnoreDragRef = useRef(false);
const [unconfirmedSessionHeight, setUnconfirmedSessionHeight] = useState(0);
const isArchived = folderType === 'archived'; const isArchived = folderType === 'archived';
const isAllFolder = folderType === 'all';
const resolvedFolderId = ( const resolvedFolderId = (
folderType === 'all' ? ALL_FOLDER_ID : isArchived ? ARCHIVED_FOLDER_ID : folderId! isAllFolder ? ALL_FOLDER_ID : isArchived ? ARCHIVED_FOLDER_ID : folderId!
); );
const shouldDisplayArchive = folderType === 'all' && canDisplayArchive; const shouldDisplayArchive = isAllFolder && canDisplayArchive;
const orderedIds = useFolderManagerForOrderedIds(resolvedFolderId); const orderedIds = useFolderManagerForOrderedIds(resolvedFolderId);
useUserStoriesPolling(orderedIds); useUserStoriesPolling(orderedIds);
@ -92,6 +99,18 @@ const ChatList: FC<OwnProps> = ({
const [viewportIds, getMore] = useInfiniteScroll(undefined, orderedIds, undefined, CHAT_LIST_SLICE); const [viewportIds, getMore] = useInfiniteScroll(undefined, orderedIds, undefined, CHAT_LIST_SLICE);
const shouldShowUnconfirmedSessions = useMemo(() => {
const sessionsArray = Object.values(sessions || {});
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]);
useEffect(() => {
if (!shouldShowUnconfirmedSessions) setUnconfirmedSessionHeight(0);
}, [shouldShowUnconfirmedSessions]);
// Support <Alt>+<Up/Down> to navigate between chats // Support <Alt>+<Up/Down> to navigate between chats
useHotkeys(isActive && orderedIds?.length ? { useHotkeys(isActive && orderedIds?.length ? {
'Alt+ArrowUp': (e: KeyboardEvent) => { 'Alt+ArrowUp': (e: KeyboardEvent) => {
@ -189,7 +208,7 @@ const ChatList: FC<OwnProps> = ({
return viewportIds!.map((id, i) => { return viewportIds!.map((id, i) => {
const isPinned = viewportOffset + i < pinnedCount; const isPinned = viewportOffset + i < pinnedCount;
const offsetTop = archiveHeight + (viewportOffset + i) * CHAT_HEIGHT_PX; const offsetTop = unconfirmedSessionHeight + archiveHeight + (viewportOffset + i) * CHAT_HEIGHT_PX;
return ( return (
<Chat <Chat
@ -217,10 +236,17 @@ const ChatList: FC<OwnProps> = ({
preloadBackwards={CHAT_LIST_SLICE} preloadBackwards={CHAT_LIST_SLICE}
withAbsolutePositioning withAbsolutePositioning
beforeChildren={renderedOverflowTrigger} beforeChildren={renderedOverflowTrigger}
maxHeight={chatsHeight + archiveHeight} maxHeight={chatsHeight + archiveHeight + unconfirmedSessionHeight}
onLoadMore={getMore} onLoadMore={getMore}
onDragLeave={handleDragLeave} onDragLeave={handleDragLeave}
> >
{shouldShowUnconfirmedSessions && (
<UnconfirmedSession
key="unconfirmed"
sessions={sessions!}
onHeightChange={setUnconfirmedSessionHeight}
/>
)}
{shouldDisplayArchive && ( {shouldDisplayArchive && (
<Archive <Archive
key="archive" key="archive"

View File

@ -0,0 +1,32 @@
/* stylelint-disable-next-line */
@value minimized from "./Archive.module.scss";
.root {
padding: 0.5rem;
text-align: center;
& + :global(.minimized) {
margin-top: 0 !important;
}
}
.title {
font-size: 1rem;
}
.info {
font-size: 0.875rem;
color: var(--color-text-secondary);
margin-bottom: 0.5rem;
}
.buttons {
display: flex;
justify-content: space-around;
column-gap: 1rem;
}
.button {
font-size: 0.875rem;
font-weight: 500;
}

View File

@ -0,0 +1,72 @@
import React, { memo, useMemo, useRef } from '../../../lib/teact/teact';
import { getActions } from '../../../global';
import type { ApiSession } from '../../../api/types';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useResizeObserver from '../../../hooks/useResizeObserver';
import Button from '../../ui/Button';
import styles from './UnconfirmedSession.module.scss';
type OwnProps = {
sessions: Record<string, ApiSession>;
onHeightChange: (height: number) => void;
};
const UnconfirmedSession = ({ sessions, onHeightChange } : OwnProps) => {
const { changeSessionSettings, terminateAuthorization, showNotification } = getActions();
// eslint-disable-next-line no-null/no-null
const ref = useRef<HTMLDivElement>(null);
const lang = useLang();
useResizeObserver(ref, (entry) => {
const height = entry.borderBoxSize?.[0]?.blockSize || entry.contentRect.height;
onHeightChange(height);
});
const firstUnconfirmed = useMemo(() => {
return Object.values(sessions).sort((a, b) => b.dateCreated - a.dateCreated)
.find((session) => session.isUnconfirmed)!;
}, [sessions]);
const locationString = useMemo(() => {
return [firstUnconfirmed.deviceModel, firstUnconfirmed.region, firstUnconfirmed.country].filter(Boolean).join(', ');
}, [firstUnconfirmed]);
const handleAccept = useLastCallback(() => {
changeSessionSettings({
hash: firstUnconfirmed.hash,
isConfirmed: true,
});
});
const handleReject = useLastCallback(() => {
terminateAuthorization({ hash: firstUnconfirmed.hash });
showNotification({
title: lang('UnconfirmedAuthDeniedTitle', 1),
message: lang('UnconfirmedAuthDeniedMessageSingle', locationString),
});
});
return (
<div className={styles.root} ref={ref}>
<h2 className={styles.title}>{lang('UnconfirmedAuthTitle')}</h2>
<p className={styles.info}>
{lang('UnconfirmedAuthSingle', locationString)}
</p>
<div className={styles.buttons}>
<Button fluid isText size="smaller" className={styles.button} onClick={handleAccept}>
{lang('UnconfirmedAuthConfirm')}
</Button>
<Button fluid isText size="smaller" color="danger" onClick={handleReject} className={styles.button}>
{lang('UnconfirmedAuthDeny')}
</Button>
</div>
</div>
);
};
export default memo(UnconfirmedSession);

View File

@ -40,7 +40,6 @@ const SettingsMain: FC<OwnProps & StateProps> = ({
}) => { }) => {
const { const {
loadProfilePhotos, loadProfilePhotos,
loadAuthorizations,
openPremiumModal, openPremiumModal,
openSupportChat, openSupportChat,
openUrl, openUrl,
@ -61,10 +60,6 @@ const SettingsMain: FC<OwnProps & StateProps> = ({
onBack: onReset, onBack: onReset,
}); });
useEffect(() => {
loadAuthorizations();
}, []);
const handleOpenSupport = useLastCallback(() => { const handleOpenSupport = useLastCallback(() => {
openSupportChat(); openSupportChat();
closeSupportDialog(); closeSupportDialog();

View File

@ -68,7 +68,6 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
const { const {
loadPrivacySettings, loadPrivacySettings,
loadBlockedUsers, loadBlockedUsers,
loadAuthorizations,
loadContentSettings, loadContentSettings,
updateContentSettings, updateContentSettings,
loadGlobalPrivacySettings, loadGlobalPrivacySettings,
@ -80,7 +79,6 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
useEffect(() => { useEffect(() => {
loadBlockedUsers(); loadBlockedUsers();
loadAuthorizations();
loadPrivacySettings(); loadPrivacySettings();
loadContentSettings(); loadContentSettings();
loadWebAuthorizations(); loadWebAuthorizations();

View File

@ -254,6 +254,7 @@ const Main: FC<OwnProps & StateProps> = ({
loadFeaturedEmojiStickers, loadFeaturedEmojiStickers,
setIsElectronUpdateAvailable, setIsElectronUpdateAvailable,
loadPremiumSetStickers, loadPremiumSetStickers,
loadAuthorizations,
} = getActions(); } = getActions();
if (DEBUG && !DEBUG_isLogged) { if (DEBUG && !DEBUG_isLogged) {
@ -327,6 +328,7 @@ const Main: FC<OwnProps & StateProps> = ({
loadTopReactions(); loadTopReactions();
loadRecentReactions(); loadRecentReactions();
loadFeaturedEmojiStickers(); loadFeaturedEmojiStickers();
loadAuthorizations();
} }
}, [isMasterTab, isSynced]); }, [isMasterTab, isSynced]);

View File

@ -51,7 +51,7 @@ export const CUSTOM_EMOJI_PREVIEW_CACHE_DISABLED = false;
export const CUSTOM_EMOJI_PREVIEW_CACHE_NAME = 'tt-custom-emoji-preview'; export const CUSTOM_EMOJI_PREVIEW_CACHE_NAME = 'tt-custom-emoji-preview';
export const MEDIA_CACHE_MAX_BYTES = 512 * 1024; // 512 KB export const MEDIA_CACHE_MAX_BYTES = 512 * 1024; // 512 KB
export const CUSTOM_BG_CACHE_NAME = 'tt-custom-bg'; export const CUSTOM_BG_CACHE_NAME = 'tt-custom-bg';
export const LANG_CACHE_NAME = 'tt-lang-packs-v23'; export const LANG_CACHE_NAME = 'tt-lang-packs-v24';
export const ASSET_CACHE_NAME = 'tt-assets'; export const ASSET_CACHE_NAME = 'tt-assets';
export const AUTODOWNLOAD_FILESIZE_MB_LIMITS = [1, 5, 10, 50, 100, 500]; export const AUTODOWNLOAD_FILESIZE_MB_LIMITS = [1, 5, 10, 50, 100, 500];
export const DATA_BROADCAST_CHANNEL_NAME = 'tt-global'; export const DATA_BROADCAST_CHANNEL_NAME = 'tt-global';
@ -301,6 +301,7 @@ export const MINI_APP_TOS_URL = 'https://telegram.org/tos/mini-apps';
export const GENERAL_TOPIC_ID = 1; export const GENERAL_TOPIC_ID = 1;
export const STORY_EXPIRE_PERIOD = 86400; // 1 day export const STORY_EXPIRE_PERIOD = 86400; // 1 day
export const STORY_VIEWERS_EXPIRE_PERIOD = 86400; // 1 day export const STORY_VIEWERS_EXPIRE_PERIOD = 86400; // 1 day
export const FRESH_AUTH_PERIOD = 86400; // 1 day
export const LIGHT_THEME_BG_COLOR = '#99BA92'; export const LIGHT_THEME_BG_COLOR = '#99BA92';
export const DARK_THEME_BG_COLOR = '#0F0F0F'; export const DARK_THEME_BG_COLOR = '#0F0F0F';

View File

@ -135,11 +135,14 @@ addActionHandler('terminateAllAuthorizations', async (global): Promise<void> =>
}); });
addActionHandler('changeSessionSettings', async (global, actions, payload): Promise<void> => { addActionHandler('changeSessionSettings', async (global, actions, payload): Promise<void> => {
const { hash, areCallsEnabled, areSecretChatsEnabled } = payload; const {
hash, areCallsEnabled, areSecretChatsEnabled, isConfirmed,
} = payload;
const result = await callApi('changeSessionSettings', { const result = await callApi('changeSessionSettings', {
hash, hash,
areCallsEnabled, areCallsEnabled,
areSecretChatsEnabled, areSecretChatsEnabled,
isConfirmed,
}); });
if (!result) { if (!result) {
@ -157,6 +160,7 @@ addActionHandler('changeSessionSettings', async (global, actions, payload): Prom
...global.activeSessions.byHash[hash], ...global.activeSessions.byHash[hash],
...(areCallsEnabled !== undefined ? { areCallsEnabled } : undefined), ...(areCallsEnabled !== undefined ? { areCallsEnabled } : undefined),
...(areSecretChatsEnabled !== undefined ? { areSecretChatsEnabled } : undefined), ...(areSecretChatsEnabled !== undefined ? { areSecretChatsEnabled } : undefined),
...(isConfirmed && { isUnconfirmed: undefined }),
}, },
}, },
}, },

View File

@ -41,6 +41,12 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
actions.loadConfig(); actions.loadConfig();
break; break;
case 'updateNewAuthorization': {
// Load more info about this session
actions.loadAuthorizations();
break;
}
case 'updateFavoriteStickers': case 'updateFavoriteStickers':
actions.loadFavoriteStickers(); actions.loadFavoriteStickers();
break; break;

View File

@ -1682,6 +1682,7 @@ export interface ActionPayloads {
hash: string; hash: string;
areCallsEnabled?: boolean; areCallsEnabled?: boolean;
areSecretChatsEnabled?: boolean; areSecretChatsEnabled?: boolean;
isConfirmed?: boolean;
}; };
changeSessionTtl: { changeSessionTtl: {
days: number; days: number;