2025-12-23 12:50:30 +01:00

346 lines
9.7 KiB
TypeScript

import type { ActionReturnType } from '../../types';
import { PaymentStep } from '../../../types';
import { SERVICE_NOTIFICATIONS_USER_ID } from '../../../config';
import { applyLangPackDifference, getTranslationFn, requestLangPackDifference } from '../../../util/localization';
import { getPeerTitle } from '../../helpers/peers';
import { addActionHandler, setGlobal } from '../../index';
import {
addBlockedUser,
addChats,
addStoriesForPeer,
addUsers,
removeBlockedUser,
removePeerStory,
replaceWebPage,
setConfirmPaymentUrl,
setPaymentStep,
updateFullWebPage,
updateLastReadStoryForPeer,
updatePeerStory,
updatePeersWithStories,
updatePoll,
updateStealthMode,
updateThreadInfos,
} from '../../reducers';
import { updateTabState } from '../../reducers/tabs';
import {
selectPeer,
selectPeerStories,
selectPeerStory,
selectTabState,
} from '../../selectors';
addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
switch (update['@type']) {
case 'updateEntities': {
const {
users, chats, threadInfos, polls, webPages,
} = update;
if (users) global = addUsers(global, users);
if (chats) global = addChats(global, chats);
if (threadInfos) global = updateThreadInfos(global, threadInfos);
if (polls) {
polls.forEach((poll) => {
global = updatePoll(global, poll.id, poll);
});
}
if (webPages) {
webPages.forEach((webPage) => {
if (webPage.webpageType === 'full') {
global = updateFullWebPage(global, webPage.id, webPage);
} else {
global = replaceWebPage(global, webPage.id, webPage);
}
});
}
setGlobal(global);
break;
}
case 'updatePeerBlocked':
if (update.isBlocked) {
return addBlockedUser(global, update.id);
} else if (update.isBlockedFromStories) {
return global; // Unsupported
} else {
return removeBlockedUser(global, update.id);
}
case 'updateResetContactList':
global = {
...global,
contactList: {
userIds: [],
},
};
setGlobal(global);
break;
case 'updateConfig':
actions.loadConfig();
break;
case 'updateNewAuthorization': {
// Load more info about this session
actions.loadAuthorizations();
break;
}
case 'updateFavoriteStickers':
actions.loadFavoriteStickers();
break;
case 'updateRecentStickers':
actions.loadRecentStickers();
break;
case 'updateRecentReactions':
actions.loadRecentReactions();
break;
case 'updateRecentEmojiStatuses':
actions.loadRecentEmojiStatuses();
break;
case 'updateSavedReactionTags':
actions.loadSavedReactionTags();
break;
case 'updateMoveStickerSetToTop': {
const oldOrder = update.isCustomEmoji ? global.customEmojis.added.setIds : global.stickers.added.setIds;
if (!oldOrder?.some((id) => id === update.id)) return global;
const newOrder = [update.id, ...oldOrder.filter((id) => id !== update.id)];
actions.reorderStickerSets({ order: newOrder, isCustomEmoji: update.isCustomEmoji });
break;
}
case 'updateStickerSets':
actions.loadStickerSets();
break;
case 'updateStickerSetsOrder': {
// Filter out invalid set IDs, which may be sent by the server
const order = update.order.filter((setId) => Boolean(global.stickers.setsById[setId]));
actions.reorderStickerSets({ order, isCustomEmoji: update.isCustomEmoji });
break;
}
case 'updateSavedGifs':
actions.loadSavedGifs();
break;
case 'updatePrivacy':
global = {
...global,
settings: {
...global.settings,
privacy: {
...global.settings.privacy,
[update.key]: update.rules,
},
},
};
setGlobal(global);
break;
case 'updatePaymentVerificationNeeded':
Object.values(global.byTabId).forEach(({ id: tabId }) => {
global = setConfirmPaymentUrl(global, update.url, tabId);
global = setPaymentStep(global, PaymentStep.ConfirmPayment, tabId);
});
setGlobal(global);
break;
case 'updateWebViewResultSent':
Object.values(global.byTabId).forEach((tabState) => {
Object.entries(tabState.webApps.openedWebApps).forEach(([webAppKey, webApp]) => {
if (webApp.queryId === update.queryId) {
actions.resetDraftReplyInfo({ tabId: tabState.id });
actions.closeWebApp({ key: webAppKey, tabId: tabState.id });
}
});
});
break;
case 'updateWebPage': {
const { webPage } = update;
if (webPage.webpageType === 'full') {
global = updateFullWebPage(global, webPage.id, webPage);
} else {
global = replaceWebPage(global, webPage.id, webPage);
}
setGlobal(global);
break;
}
case 'updateStory':
global = addStoriesForPeer(global, update.peerId, { [update.story.id]: update.story });
global = updatePeersWithStories(global, { [update.peerId]: selectPeerStories(global, update.peerId)! });
setGlobal(global);
break;
case 'deleteStory':
global = removePeerStory(global, update.peerId, update.storyId);
setGlobal(global);
break;
case 'updateReadStories':
global = updateLastReadStoryForPeer(global, update.peerId, update.lastReadId);
setGlobal(global);
break;
case 'updateSentStoryReaction': {
const { peerId, storyId, reaction } = update;
const story = selectPeerStory(global, peerId, storyId);
if (!story) return global;
global = updatePeerStory(global, peerId, storyId, { sentReaction: reaction });
setGlobal(global);
break;
}
case 'updateStealthMode':
global = updateStealthMode(global, update.stealthMode);
setGlobal(global);
break;
case 'updateAttachMenuBots':
actions.loadAttachBots();
break;
case 'updatePremiumFloodWait': {
actions.processPremiumFloodWait({
isUpload: update.isUpload,
});
break;
}
case 'updatePaidReactionPrivacy': {
global = {
...global,
settings: {
...global.settings,
paidReactionPrivacy: update.private,
},
};
setGlobal(global);
break;
}
case 'updateLangPackTooLong': {
requestLangPackDifference(update.langCode);
break;
}
case 'updateLangPack': {
applyLangPackDifference(update.version, update.strings, update.keysToRemove);
break;
}
case 'newMessage': {
const action = update.message.content?.action;
if (action?.type === 'starGift' && update.message.isOutgoing) {
const { gift } = action;
if (!gift.isAuction || update.message.chatId === SERVICE_NOTIFICATIONS_USER_ID) return undefined;
const { chatId, id } = update.message;
if (!chatId || !id) return;
Object.values(global.byTabId).forEach(({ id: tabId }) => {
actions.focusMessage({
chatId,
messageId: id,
tabId,
});
actions.closeGiftAuctionBidModal({ tabId });
actions.closeGiftModal({ tabId });
actions.showNotification({
icon: 'auction-filled',
message: {
key: 'GiftAuctionWonNotification',
variables: {
gift: gift.title,
},
},
tabId,
});
actions.requestConfetti({ withStars: true, tabId });
});
return undefined;
}
if (!update.message.isOutgoing && update.message.chatId !== SERVICE_NOTIFICATIONS_USER_ID) return undefined;
if (action?.type !== 'starGiftUnique') return undefined;
const actionStarGift = action.gift;
Object.values(global.byTabId).forEach(({ id: tabId }) => {
const tabState = selectTabState(global, tabId);
if (tabState.isWaitingForStarGiftUpgrade) {
actions.openUniqueGiftBySlug({
slug: actionStarGift.slug,
tabId,
});
actions.showNotification({
title: { key: 'GiftUpgradedTitle' },
message: { key: 'GiftUpgradedDescription' },
tabId,
});
actions.requestConfetti({ withStars: true, tabId });
global = updateTabState(global, {
isWaitingForStarGiftUpgrade: undefined,
}, tabId);
}
if (tabState.isWaitingForStarGiftTransfer) {
const chatId = update.message.chatId;
const receiver = chatId ? selectPeer(global, chatId) : undefined;
if (receiver) {
actions.focusMessage({
chatId: receiver.id,
messageId: update.message.id!,
tabId,
});
actions.showNotification({
message: {
key: 'GiftTransferSuccessMessage',
variables: {
gift: {
key: 'GiftUnique',
variables: {
title: actionStarGift.title,
number: actionStarGift.number,
},
},
peer: getPeerTitle(getTranslationFn(), receiver),
},
},
tabId,
});
}
actions.requestConfetti({ withStars: true, tabId });
global = updateTabState(global, {
isWaitingForStarGiftTransfer: undefined,
}, tabId);
actions.reloadPeerSavedGifts({ peerId: global.currentUserId! });
}
});
setGlobal(global);
}
}
return undefined;
});