[Refactoring] Optimize fetching notify exceptions (#1277)

This commit is contained in:
Alexander Zinchuk 2021-07-15 21:50:29 +03:00
parent ed0eda57f1
commit e374122d85
10 changed files with 89 additions and 36 deletions

View File

@ -4,6 +4,7 @@ import { ApiSession, ApiWallpaper } from '../../types';
import { ApiPrivacySettings, ApiPrivacyKey, PrivacyVisibility } from '../../../types';
import { buildApiDocument } from './messages';
import { getApiChatIdFromMtpPeer } from './chats';
import { pick } from '../../../util/iteratees';
export function buildApiWallpaper(wallpaper: GramJs.TypeWallPaper): ApiWallpaper | undefined {
@ -96,3 +97,18 @@ export function buildPrivacyRules(rules: GramJs.TypePrivacyRule[]): ApiPrivacySe
blockChatIds: blockChatIds || [],
};
}
export function buildApiNotifyException(
notifySettings: GramJs.TypePeerNotifySettings, peer: GramJs.TypePeer, serverTimeOffset: number,
) {
const {
silent, muteUntil, showPreviews, sound,
} = notifySettings;
return {
chatId: getApiChatIdFromMtpPeer(peer),
isMuted: silent || (typeof muteUntil === 'number' && Date.now() + serverTimeOffset * 1000 < muteUntil * 1000),
...(sound === '' && { isSilent: true }),
...(showPreviews !== undefined && { shouldShowPreviews: Boolean(showPreviews) }),
};
}

View File

@ -414,7 +414,7 @@ export async function updateChatMutedState({
onUpdate({
'@type': 'updateNotifyExceptions',
id: chat.id,
chatId: chat.id,
isMuted,
});

View File

@ -2,12 +2,14 @@ import BigInt from 'big-integer';
import { Api as GramJs } from '../../../lib/gramjs';
import {
ApiChat, ApiLangString, ApiLanguage, ApiUser, ApiWallpaper,
ApiChat, ApiLangString, ApiLanguage, ApiNotifyException, ApiUser, ApiWallpaper,
} from '../../types';
import { ApiPrivacyKey, IInputPrivacyRules } from '../../../types';
import { BLOCKED_LIST_LIMIT, DEFAULT_LANG_PACK } from '../../../config';
import { buildApiWallpaper, buildApiSession, buildPrivacyRules } from '../apiBuilders/misc';
import {
buildApiWallpaper, buildApiSession, buildPrivacyRules, buildApiNotifyException,
} from '../apiBuilders/misc';
import { buildApiUser } from '../apiBuilders/users';
import { buildApiChatFromPreview, getApiChatIdFromMtpPeer } from '../apiBuilders/chats';
@ -156,12 +158,26 @@ export function terminateAllAuthorizations() {
return invokeRequest(new GramJs.auth.ResetAuthorizations());
}
export async function fetchNotificationExceptions() {
const result = await invokeRequest(new GramJs.account.GetNotifyExceptions({ compareSound: true }), true);
export async function fetchNotificationExceptions({
serverTimeOffset,
}: { serverTimeOffset: number }) {
const result = await invokeRequest(new GramJs.account.GetNotifyExceptions({ compareSound: true }));
if (result instanceof GramJs.Updates || result instanceof GramJs.UpdatesCombined) {
updateLocalDb(result);
if (!(result instanceof GramJs.Updates || result instanceof GramJs.UpdatesCombined)) {
return undefined;
}
updateLocalDb(result);
return result.updates.reduce((acc, update) => {
if (!(update instanceof GramJs.UpdateNotifySettings && update.peer instanceof GramJs.NotifyPeer)) {
return acc;
}
acc.push(buildApiNotifyException(update.notifySettings, update.peer.peer, serverTimeOffset));
return acc;
}, [] as ApiNotifyException[]);
}
export async function fetchNotificationSettings({

View File

@ -33,7 +33,7 @@ import localDb from './localDb';
import { omitVirtualClassFields } from './apiBuilders/helpers';
import { DEBUG } from '../../config';
import { addMessageToLocalDb, addPhotoToLocalDb, resolveMessageApiChatId } from './helpers';
import { buildPrivacyKey, buildPrivacyRules } from './apiBuilders/misc';
import { buildApiNotifyException, buildPrivacyKey, buildPrivacyRules } from './apiBuilders/misc';
import { buildApiPhoto } from './apiBuilders/common';
type Update = (
@ -548,19 +548,9 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
update instanceof GramJs.UpdateNotifySettings
&& update.peer instanceof GramJs.NotifyPeer
) {
const {
silent, muteUntil, showPreviews, sound,
} = update.notifySettings;
const isMuted = silent
|| (typeof muteUntil === 'number' && Date.now() + serverTimeOffset * 1000 < muteUntil * 1000);
onUpdate({
'@type': 'updateNotifyExceptions',
id: getApiChatIdFromMtpPeer(update.peer.peer),
isMuted,
...(sound === '' && { isSilent: true }),
...(showPreviews !== undefined && { shouldShowPreviews: Boolean(showPreviews) }),
...buildApiNotifyException(update.notifySettings, update.peer.peer, serverTimeOffset),
});
} else if (
update instanceof GramJs.UpdateUserTyping

View File

@ -60,3 +60,10 @@ export interface ApiSessionData {
keys: Record<number, string | number[]>;
hashes: Record<number, string | number[]>;
}
export type ApiNotifyException = {
chatId: number;
isMuted: boolean;
isSilent?: boolean;
shouldShowPreviews?: boolean;
};

View File

@ -9,7 +9,7 @@ import {
ApiFormattedText, ApiMessage, ApiPhoto, ApiPoll, ApiStickerSet, ApiThreadInfo,
} from './messages';
import { ApiUser, ApiUserFullInfo, ApiUserStatus } from './users';
import { ApiSessionData } from './misc';
import { ApiNotifyException, ApiSessionData } from './misc';
export type ApiUpdateReady = {
'@type': 'updateApiReady';
@ -358,11 +358,7 @@ export type ApiUpdateNotifySettings = {
export type ApiUpdateNotifyExceptions = {
'@type': 'updateNotifyExceptions';
id: number;
isMuted: boolean;
isSilent?: boolean;
shouldShowPreviews?: boolean;
};
} & ApiNotifyException;
export type updateTwoFaStateWaitCode = {
'@type': 'updateTwoFaStateWaitCode';

View File

@ -11,6 +11,7 @@ import { buildCollectionByKey } from '../../../util/iteratees';
import { selectUser } from '../../selectors';
import {
addUsers, addBlockedContact, updateChats, updateUser, removeBlockedContact, replaceSettings, updateNotifySettings,
addNotifyExceptions,
} from '../../reducers';
import { isChatPrivate } from '../../helpers';
@ -304,8 +305,17 @@ addReducer('terminateAllAuthorizations', () => {
})();
});
addReducer('loadNotificationExceptions', () => {
callApi('fetchNotificationExceptions');
addReducer('loadNotificationExceptions', (global) => {
const { serverTimeOffset } = global;
(async () => {
const result = await callApi('fetchNotificationExceptions', { serverTimeOffset });
if (!result) {
return;
}
setGlobal(addNotifyExceptions(getGlobal(), result));
})();
});
addReducer('loadNotificationSettings', (global) => {

View File

@ -12,15 +12,15 @@ addReducer('apiUpdate', (global, actions, update: ApiUpdate): GlobalState | unde
case 'updateNotifyExceptions': {
const {
id, isMuted, isSilent, shouldShowPreviews,
chatId, isMuted, isSilent, shouldShowPreviews,
} = update;
const chat = global.chats.byId[id];
const chat = global.chats.byId[chatId];
if (chat) {
global = updateChat(global, id, { isMuted });
global = updateChat(global, chatId, { isMuted });
}
setGlobal(addNotifyException(global, id, { isMuted, isSilent, shouldShowPreviews }));
setGlobal(addNotifyException(global, chatId, { isMuted, isSilent, shouldShowPreviews }));
break;
}
}

View File

@ -2,6 +2,7 @@ import { GlobalState } from '../../global/types';
import {
ISettings, IThemeSettings, ThemeKey, NotifyException,
} from '../../types';
import { ApiNotifyException } from '../../api/types';
export function replaceSettings(global: GlobalState, newSettings?: Partial<ISettings>): GlobalState {
return {
@ -34,6 +35,17 @@ export function replaceThemeSettings(
};
}
export function addNotifyExceptions(
global: GlobalState, notifyExceptions: ApiNotifyException[],
): GlobalState {
notifyExceptions.forEach((notifyException) => {
const { chatId, ...exceptionData } = notifyException;
global = addNotifyException(global, chatId, exceptionData);
});
return global;
}
export function addNotifyException(
global: GlobalState, id: number, notifyException: NotifyException,
): GlobalState {

View File

@ -14,7 +14,7 @@ import {
selectIsChatMuted,
} from '../modules/helpers';
import { getTranslation } from './langProvider';
import { replaceSettings } from '../modules/reducers';
import { addNotifyExceptions, replaceSettings } from '../modules/reducers';
import {
selectChatMessage, selectNotifyExceptions, selectNotifySettings, selectUser,
} from '../modules/selectors';
@ -132,15 +132,21 @@ let areSettingsLoaded = false;
// Load notification settings from the api
async function loadNotificationSettings() {
if (areSettingsLoaded) return;
const [result] = await Promise.all([
const [resultSettings, resultExceptions] = await Promise.all([
callApi('fetchNotificationSettings', {
serverTimeOffset: getGlobal().serverTimeOffset,
}),
callApi('fetchNotificationExceptions'),
callApi('fetchNotificationExceptions', {
serverTimeOffset: getGlobal().serverTimeOffset,
}),
]);
if (!result) return;
if (!resultSettings) return;
setGlobal(replaceSettings(getGlobal(), result));
let global = replaceSettings(getGlobal(), resultSettings);
if (resultExceptions) {
global = addNotifyExceptions(global, resultExceptions);
}
setGlobal(global);
areSettingsLoaded = true;
}