From 1a98953d014b18568e05808b2c17b2a051500fb1 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Fri, 22 Mar 2024 13:05:48 +0100 Subject: [PATCH] Archive: Keep previous list on reload (#4334) --- src/config.ts | 1 + src/global/actions/api/chats.ts | 10 +++++++-- src/global/cache.ts | 40 +++++++++++++++++++-------------- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/config.ts b/src/config.ts index bc46a6081..117bcd2a5 100644 --- a/src/config.ts +++ b/src/config.ts @@ -40,6 +40,7 @@ export const GLOBAL_STATE_CACHE_DISABLED = false; export const GLOBAL_STATE_CACHE_KEY = 'tt-global-state'; export const GLOBAL_STATE_CACHE_USER_LIST_LIMIT = 500; export const GLOBAL_STATE_CACHE_CHAT_LIST_LIMIT = 200; +export const GLOBAL_STATE_CACHE_ARCHIVED_CHAT_LIST_LIMIT = 10; export const GLOBAL_STATE_CACHE_CUSTOM_EMOJI_LIMIT = 150; export const MEDIA_CACHE_DISABLED = false; diff --git a/src/global/actions/api/chats.ts b/src/global/actions/api/chats.ts index 7c1d84948..334cad4e7 100644 --- a/src/global/actions/api/chats.ts +++ b/src/global/actions/api/chats.ts @@ -20,6 +20,7 @@ import { ARCHIVED_FOLDER_ID, CHAT_LIST_LOAD_SLICE, DEBUG, + GLOBAL_STATE_CACHE_ARCHIVED_CHAT_LIST_LIMIT, RE_TG_LINK, SAVED_FOLDER_ID, SERVICE_NOTIFICATIONS_USER_ID, @@ -506,7 +507,7 @@ addActionHandler('loadAllChats', async (global, actions, payload): Promise let i = 0; const getOrderDate = (chat: ApiChat) => { - return selectChatLastMessage(global, chat.id)?.date || chat.creationDate; + return selectChatLastMessage(global, chat.id, listType === 'saved' ? 'saved' : 'all')?.date || chat.creationDate; }; while (shouldReplace || !global.chats.isFullyLoaded[listType]) { @@ -2704,10 +2705,15 @@ async function loadChats( } const tabStates = Object.values(global.byTabId); + const topArchivedChats = getOrderedIds(ARCHIVED_FOLDER_ID) + ?.slice(0, GLOBAL_STATE_CACHE_ARCHIVED_CHAT_LIST_LIMIT) + .map((chatId) => selectChat(global, chatId)) + .filter(Boolean); const visibleChats = tabStates.flatMap(({ id: tabId }) => { const currentChat = selectCurrentChat(global, tabId); return currentChat ? [currentChat] : []; }); + const chatsToSave = visibleChats.concat(topArchivedChats || []); const visibleUsers = tabStates.flatMap(({ id: tabId }) => { return selectVisibleUsers(global, tabId) || []; @@ -2719,7 +2725,7 @@ async function loadChats( global = replaceUsers(global, buildCollectionByKey(visibleUsers.concat(result.users), 'id')); global = replaceUserStatuses(global, result.userStatusesById); - global = replaceChats(global, buildCollectionByKey(visibleChats.concat(result.chats), 'id')); + global = replaceChats(global, buildCollectionByKey(chatsToSave.concat(result.chats), 'id')); global = replaceChatListIds(global, listType, chatIds); } else { // Archived and Saved diff --git a/src/global/cache.ts b/src/global/cache.ts index c5fa74743..8fef9b36e 100644 --- a/src/global/cache.ts +++ b/src/global/cache.ts @@ -2,6 +2,7 @@ import { addCallback, removeCallback } from '../lib/teact/teactn'; import type { ApiAvailableReaction, ApiMessage } from '../api/types'; +import type { ThreadId } from '../types'; import type { ActionReturnType, GlobalState, MessageList } from './types'; import { MAIN_THREAD_ID } from '../api/types'; @@ -12,6 +13,7 @@ import { ARCHIVED_FOLDER_ID, DEBUG, DEFAULT_LIMITS, + GLOBAL_STATE_CACHE_ARCHIVED_CHAT_LIST_LIMIT, GLOBAL_STATE_CACHE_CHAT_LIST_LIMIT, GLOBAL_STATE_CACHE_CUSTOM_EMOJI_LIMIT, GLOBAL_STATE_CACHE_DISABLED, @@ -342,8 +344,8 @@ function reduceUsers(global: T): GlobalState['users'] { ...chatStoriesUserIds, ...visibleUserIds || [], ...global.topPeers.userIds || [], + ...getOrderedIds(ARCHIVED_FOLDER_ID)?.slice(0, GLOBAL_STATE_CACHE_ARCHIVED_CHAT_LIST_LIMIT).filter(isUserId) || [], ...getOrderedIds(ALL_FOLDER_ID)?.filter(isUserId) || [], - ...getOrderedIds(ARCHIVED_FOLDER_ID)?.filter(isUserId) || [], ...global.contactList?.userIds || [], ...global.recentlyFoundChatIds?.filter(isUserId) || [], ...Object.keys(byId), @@ -384,9 +386,9 @@ function reduceChats(global: T): GlobalState['chats'] { ...currentUserId ? [currentUserId] : [], ...currentChatIds, ...messagesChatIds, - ...getOrderedIds(SAVED_FOLDER_ID) || [], + ...getOrderedIds(ARCHIVED_FOLDER_ID)?.slice(0, GLOBAL_STATE_CACHE_ARCHIVED_CHAT_LIST_LIMIT) || [], ...getOrderedIds(ALL_FOLDER_ID) || [], - ...getOrderedIds(ARCHIVED_FOLDER_ID) || [], + ...getOrderedIds(SAVED_FOLDER_ID) || [], ...global.recentlyFoundChatIds || [], ...Object.keys(byId), ]).slice(0, GLOBAL_STATE_CACHE_CHAT_LIST_LIMIT); @@ -420,8 +422,21 @@ function reduceMessages(global: T): GlobalState['messages ...currentUserId ? [currentUserId] : [], ...forumPanelChatIds, ...getOrderedIds(ALL_FOLDER_ID) || [], + ...getOrderedIds(ARCHIVED_FOLDER_ID)?.slice(0, GLOBAL_STATE_CACHE_ARCHIVED_CHAT_LIST_LIMIT) || [], ]); + const openedChatThreadIds = Object.values(global.byTabId).reduce((acc, { id: tabId }) => { + const { chatId: tabChatId, threadId } = selectCurrentMessageList(global, tabId) || {}; + if (!tabChatId || !threadId || threadId === MAIN_THREAD_ID) { + return acc; + } + const current = acc[tabChatId] || new Set(); + current.add(threadId); + acc[tabChatId] = current; + + return acc; + }, {} as Record>); + chatIdsToSave.forEach((chatId) => { const current = global.messages.byChatId[chatId]; if (!current) { @@ -431,22 +446,13 @@ function reduceMessages(global: T): GlobalState['messages const chat = selectChat(global, chatId); const chatLastMessageId = selectChatLastMessageId(global, chatId); - const threadIds = unique(compact(Object.values(global.byTabId).map(({ id: tabId }) => { - const { chatId: tabChatId, threadId } = selectCurrentMessageList(global, tabId) || {}; - if (!tabChatId || tabChatId !== chatId || !threadId || threadId === MAIN_THREAD_ID) { - return undefined; - } - - return threadId; - }).concat( - Object.values(global.messages.byChatId[chatId].threadsById || {}) - .map(({ threadInfo }) => (threadInfo?.isCommentsInfo ? threadInfo?.originMessageId : undefined)), - ))); + const openedThreadIds = Array.from(openedChatThreadIds[chatId] || []); + const commentThreadIds = Object.values(global.messages.byChatId[chatId].threadsById || {}) + .map(({ threadInfo }) => (threadInfo?.isCommentsInfo ? threadInfo?.originMessageId : undefined)) + .filter(Boolean); + const threadIds = unique(openedThreadIds.concat(commentThreadIds)); const threadsToSave = pickTruthy(current.threadsById, [MAIN_THREAD_ID, ...threadIds]); - if (!Object.keys(threadsToSave).length) { - return; - } const viewportIdsToSave = unique(Object.values(threadsToSave).flatMap((thread) => thread.lastViewportIds || [])); const topicLastMessageIds = chat?.topics ? Object.values(chat.topics).map(({ lastMessageId }) => lastMessageId)