import { addActionHandler, getActions, getGlobal, setGlobal, } from '../../index'; import type { ApiChat } from '../../../api/types'; import { MAIN_THREAD_ID } from '../../../api/types'; import { MESSAGE_SEARCH_SLICE, SHARED_MEDIA_SLICE } from '../../../config'; import { callApi } from '../../../api/gramjs'; import { selectCurrentTextSearch, selectCurrentMediaSearch, selectCurrentMessageList, selectChat, selectThreadInfo, } from '../../selectors'; import { buildCollectionByKey } from '../../../util/iteratees'; import { addChatMessagesById, addChats, addUsers, updateLocalMediaSearchResults, updateLocalTextSearchResults, } from '../../reducers'; import type { SharedMediaType } from '../../../types'; addActionHandler('searchTextMessagesLocal', (global) => { const { chatId, threadId } = selectCurrentMessageList(global) || {}; const chat = chatId ? selectChat(global, chatId) : undefined; const currentSearch = selectCurrentTextSearch(global); if (!chat || !currentSearch || !threadId) { return; } const { query, results } = currentSearch; const offsetId = results?.nextOffsetId; let topMessageId: number | undefined; if (threadId !== MAIN_THREAD_ID) { const threadInfo = selectThreadInfo(global, chatId!, threadId); topMessageId = threadInfo?.topMessageId; } void searchTextMessages(chat, threadId, topMessageId, query, offsetId); }); addActionHandler('searchMediaMessagesLocal', (global) => { const { chatId } = selectCurrentMessageList(global) || {}; if (!chatId) { return; } const chat = selectChat(global, chatId); const currentSearch = selectCurrentMediaSearch(global); if (!chat || !currentSearch) { return; } const { currentType: type, resultsByType } = currentSearch; const currentResults = type && resultsByType && resultsByType[type]; const offsetId = currentResults?.nextOffsetId; if (!type) { return; } void searchSharedMedia(chat, type, offsetId); }); addActionHandler('searchMessagesByDate', (global, actions, payload) => { const { timestamp } = payload!; const { chatId } = selectCurrentMessageList(global) || {}; if (!chatId) { return; } const chat = selectChat(global, chatId); if (!chat) { return; } void searchMessagesByDate(chat, timestamp); }); async function searchTextMessages( chat: ApiChat, threadId: number, topMessageId?: number, query?: string, offsetId?: number, ) { if (!query) { return; } const result = await callApi('searchMessagesLocal', { chat, type: 'text', query, topMessageId, limit: MESSAGE_SEARCH_SLICE, offsetId, }); if (!result) { return; } const { chats, users, messages, totalCount, nextOffsetId, } = result; const byId = buildCollectionByKey(messages, 'id'); const newFoundIds = Object.keys(byId).map(Number); let global = getGlobal(); const currentSearch = selectCurrentTextSearch(global); if (!currentSearch || query !== currentSearch.query) { return; } global = addChats(global, buildCollectionByKey(chats, 'id')); global = addUsers(global, buildCollectionByKey(users, 'id')); global = addChatMessagesById(global, chat.id, byId); global = updateLocalTextSearchResults(global, chat.id, threadId, newFoundIds, totalCount, nextOffsetId); setGlobal(global); } async function searchSharedMedia( chat: ApiChat, type: SharedMediaType, offsetId?: number, isBudgetPreload = false, ) { const result = await callApi('searchMessagesLocal', { chat, type, limit: SHARED_MEDIA_SLICE * 2, offsetId, }); if (!result) { return; } const { chats, users, messages, totalCount, nextOffsetId, } = result; const byId = buildCollectionByKey(messages, 'id'); const newFoundIds = Object.keys(byId).map(Number); let global = getGlobal(); const currentSearch = selectCurrentMediaSearch(global); if (!currentSearch) { return; } global = addChats(global, buildCollectionByKey(chats, 'id')); global = addUsers(global, buildCollectionByKey(users, 'id')); global = addChatMessagesById(global, chat.id, byId); global = updateLocalMediaSearchResults(global, chat.id, type, newFoundIds, totalCount, nextOffsetId); setGlobal(global); if (!isBudgetPreload) { searchSharedMedia(chat, type, nextOffsetId, true); } } async function searchMessagesByDate(chat: ApiChat, timestamp: number) { const messageId = await callApi('findFirstMessageIdAfterDate', { chat, timestamp, }); if (!messageId) { return; } getActions().focusMessage({ chatId: chat.id, messageId, }); }