Message List: Save viewport position between reloads (#6754)
This commit is contained in:
parent
ac06cb6e80
commit
214e8a3c75
@ -1323,6 +1323,12 @@ export async function markMessageListRead({
|
|||||||
chatId: chat.id,
|
chatId: chat.id,
|
||||||
topicId: Number(threadId),
|
topicId: Number(threadId),
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
sendApiUpdate({
|
||||||
|
'@type': 'updateDiscussion',
|
||||||
|
chatId: chat.id,
|
||||||
|
threadId: Number(threadId),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -753,6 +753,12 @@ export type ApiUpdateTopics = {
|
|||||||
chatId: string;
|
chatId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ApiUpdateDiscussion = {
|
||||||
|
'@type': 'updateDiscussion';
|
||||||
|
chatId: string;
|
||||||
|
threadId: number;
|
||||||
|
};
|
||||||
|
|
||||||
export type ApiUpdateViewForumAsMessages = {
|
export type ApiUpdateViewForumAsMessages = {
|
||||||
'@type': 'updateViewForumAsMessages';
|
'@type': 'updateViewForumAsMessages';
|
||||||
chatId: string;
|
chatId: string;
|
||||||
@ -931,7 +937,7 @@ export type ApiUpdate = (
|
|||||||
ApiUpdateRecentStickers | ApiUpdateSavedGifs | ApiUpdateNewScheduledMessage | ApiUpdateMoveStickerSetToTop |
|
ApiUpdateRecentStickers | ApiUpdateSavedGifs | ApiUpdateNewScheduledMessage | ApiUpdateMoveStickerSetToTop |
|
||||||
ApiUpdateScheduledMessageSendSucceeded | ApiUpdateScheduledMessage | ApiUpdateStarPaymentStateCompleted |
|
ApiUpdateScheduledMessageSendSucceeded | ApiUpdateScheduledMessage | ApiUpdateStarPaymentStateCompleted |
|
||||||
ApiUpdateDeleteScheduledMessages | ApiUpdateResetMessages | ApiUpdateMessageTranslations |
|
ApiUpdateDeleteScheduledMessages | ApiUpdateResetMessages | ApiUpdateMessageTranslations |
|
||||||
ApiUpdateFailedMessageTranslations | ApiUpdateWebPage | ApiUpdateChatTypingDraft |
|
ApiUpdateFailedMessageTranslations | ApiUpdateWebPage | ApiUpdateChatTypingDraft | ApiUpdateDiscussion |
|
||||||
ApiUpdateTwoFaError | ApiUpdateTwoFaStateWaitCode | ApiUpdateWebViewResultSent |
|
ApiUpdateTwoFaError | ApiUpdateTwoFaStateWaitCode | ApiUpdateWebViewResultSent |
|
||||||
ApiUpdateDefaultNotifySettings | ApiUpdatePeerNotifySettings | ApiUpdatePeerBlocked | ApiUpdatePrivacy |
|
ApiUpdateDefaultNotifySettings | ApiUpdatePeerNotifySettings | ApiUpdatePeerBlocked | ApiUpdatePrivacy |
|
||||||
ApiUpdateServerTimeOffset | ApiUpdateMessageReactions | ApiUpdateSavedReactionTags |
|
ApiUpdateServerTimeOffset | ApiUpdateMessageReactions | ApiUpdateSavedReactionTags |
|
||||||
|
|||||||
@ -500,9 +500,10 @@ const Profile = ({
|
|||||||
}, [profileTab, activeTabIndex]);
|
}, [profileTab, activeTabIndex]);
|
||||||
|
|
||||||
const tabType = tabs[activeTabIndex].type;
|
const tabType = tabs[activeTabIndex].type;
|
||||||
const handleLoadCommonChats = useCallback(() => {
|
const handleLoadCommonChats = useLastCallback(() => {
|
||||||
|
if (!isSynced) return;
|
||||||
loadCommonChats({ userId: chatId });
|
loadCommonChats({ userId: chatId });
|
||||||
}, [chatId]);
|
});
|
||||||
const handleLoadPeerStories = useCallback(({ offsetId }: { offsetId: number }) => {
|
const handleLoadPeerStories = useCallback(({ offsetId }: { offsetId: number }) => {
|
||||||
loadPeerProfileStories({ peerId: chatId, offsetId });
|
loadPeerProfileStories({ peerId: chatId, offsetId });
|
||||||
}, [chatId]);
|
}, [chatId]);
|
||||||
@ -513,9 +514,10 @@ const Profile = ({
|
|||||||
loadPeerSavedGifts({ peerId: chatId });
|
loadPeerSavedGifts({ peerId: chatId });
|
||||||
}, [chatId]);
|
}, [chatId]);
|
||||||
|
|
||||||
const handleLoadMoreMembers = useCallback(() => {
|
const handleLoadMoreMembers = useLastCallback(() => {
|
||||||
|
if (!isSynced) return;
|
||||||
loadMoreMembers({ chatId });
|
loadMoreMembers({ chatId });
|
||||||
}, [chatId, loadMoreMembers]);
|
});
|
||||||
|
|
||||||
useEffectWithPrevDeps(([prevGifts]) => {
|
useEffectWithPrevDeps(([prevGifts]) => {
|
||||||
if (areDeepEqual(gifts, prevGifts)) {
|
if (areDeepEqual(gifts, prevGifts)) {
|
||||||
|
|||||||
@ -3297,6 +3297,29 @@ addActionHandler('requestCollectibleInfo', async (global, actions, payload): Pro
|
|||||||
setGlobal(global);
|
setGlobal(global);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addActionHandler('loadDiscussion', async (global, actions, payload): Promise<void> => {
|
||||||
|
const { chatId, threadId } = payload;
|
||||||
|
const chat = selectChat(global, chatId);
|
||||||
|
if (!chat) return;
|
||||||
|
|
||||||
|
const result = await callApi('fetchDiscussionMessage', {
|
||||||
|
chat,
|
||||||
|
messageId: threadId,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
global = getGlobal();
|
||||||
|
global = addMessages(global, result.messages);
|
||||||
|
global = updateThreadInfo(global, result.threadInfo);
|
||||||
|
global = updateThreadReadState(global, chatId, result.threadId, result.threadReadState);
|
||||||
|
global = updateThreadInfoLastMessageId(global, chatId, result.threadId, result.lastMessageId);
|
||||||
|
global = replaceThreadLocalStateParam(global, chatId, threadId, 'firstMessageId', result.firstMessageId);
|
||||||
|
setGlobal(global);
|
||||||
|
});
|
||||||
|
|
||||||
async function loadChats(
|
async function loadChats(
|
||||||
listType: ChatListType,
|
listType: ChatListType,
|
||||||
isFullDraftSync?: boolean,
|
isFullDraftSync?: boolean,
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import type { ActionReturnType, GlobalState } from '../../types';
|
|||||||
import { MAIN_THREAD_ID } from '../../../api/types';
|
import { MAIN_THREAD_ID } from '../../../api/types';
|
||||||
|
|
||||||
import { DEBUG, MESSAGE_LIST_SLICE, SERVICE_NOTIFICATIONS_USER_ID } from '../../../config';
|
import { DEBUG, MESSAGE_LIST_SLICE, SERVICE_NOTIFICATIONS_USER_ID } from '../../../config';
|
||||||
|
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||||
import { init as initFolderManager } from '../../../util/folderManager';
|
import { init as initFolderManager } from '../../../util/folderManager';
|
||||||
import {
|
import {
|
||||||
buildCollectionByKey, omitUndefined, pick, unique,
|
buildCollectionByKey, omitUndefined, pick, unique,
|
||||||
@ -36,6 +37,7 @@ import {
|
|||||||
selectCurrentMessageList,
|
selectCurrentMessageList,
|
||||||
selectTabState,
|
selectTabState,
|
||||||
selectTopics,
|
selectTopics,
|
||||||
|
selectViewportIds,
|
||||||
} from '../../selectors';
|
} from '../../selectors';
|
||||||
import {
|
import {
|
||||||
selectDraft,
|
selectDraft,
|
||||||
@ -108,6 +110,8 @@ async function loadAndReplaceMessages<T extends GlobalState>(global: T, actions:
|
|||||||
global = getGlobal();
|
global = getGlobal();
|
||||||
|
|
||||||
let wasReset = false;
|
let wasReset = false;
|
||||||
|
const preservedTabThreadsByTabId = preserveCurrentTabThreads(global);
|
||||||
|
const preservedCurrentThreadsByChatId = preserveCurrentThreads(global);
|
||||||
|
|
||||||
// Memoize drafts
|
// Memoize drafts
|
||||||
const draftChatIds = Object.keys(global.messages.byChatId);
|
const draftChatIds = Object.keys(global.messages.byChatId);
|
||||||
@ -127,24 +131,45 @@ async function loadAndReplaceMessages<T extends GlobalState>(global: T, actions:
|
|||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
for (const { id: tabId } of Object.values(global.byTabId)) {
|
const currentTabId = getCurrentTabId();
|
||||||
|
const tabs = Object.values(global.byTabId)
|
||||||
|
.sort(({ id: leftId }, { id: rightId }) => {
|
||||||
|
if (leftId === currentTabId) return -1;
|
||||||
|
if (rightId === currentTabId) return 1;
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const { id: tabId } of tabs) {
|
||||||
global = getGlobal();
|
global = getGlobal();
|
||||||
const { chatId: currentChatId, threadId: currentThreadId } = selectCurrentMessageList(global, tabId) || {};
|
const { chatId: currentChatId, threadId: currentThreadId } = selectCurrentMessageList(global, tabId) || {};
|
||||||
const activeThreadId = currentThreadId || MAIN_THREAD_ID;
|
const activeThreadId = currentThreadId || MAIN_THREAD_ID;
|
||||||
const currentChat = currentChatId ? global.chats.byId[currentChatId] : undefined;
|
const currentChat = currentChatId ? global.chats.byId[currentChatId] : undefined;
|
||||||
|
const currentViewportIds = currentChatId
|
||||||
|
? selectViewportIds(global, currentChatId, activeThreadId, tabId)
|
||||||
|
: undefined;
|
||||||
|
const isSavedDialog = currentChatId
|
||||||
|
? getIsSavedDialog(currentChatId, activeThreadId, global.currentUserId)
|
||||||
|
: false;
|
||||||
if (currentChatId && currentChat) {
|
if (currentChatId && currentChat) {
|
||||||
const [result, resultDiscussion] = await Promise.all([
|
const discussionChat = resolveDiscussionChat(global, currentChatId, activeThreadId);
|
||||||
|
const [result, resultDiscussion, refreshedViewportMessages] = await Promise.all([
|
||||||
loadTopMessages(
|
loadTopMessages(
|
||||||
global,
|
global,
|
||||||
currentChatId,
|
currentChatId,
|
||||||
activeThreadId,
|
activeThreadId,
|
||||||
|
currentViewportIds,
|
||||||
),
|
),
|
||||||
activeThreadId !== MAIN_THREAD_ID && !currentChat.isForum
|
discussionChat
|
||||||
&& !getIsSavedDialog(currentChat.id, activeThreadId, global.currentUserId)
|
|
||||||
? callApi('fetchDiscussionMessage', {
|
? callApi('fetchDiscussionMessage', {
|
||||||
chat: currentChat,
|
chat: discussionChat.chat,
|
||||||
messageId: Number(activeThreadId),
|
messageId: discussionChat.messageId,
|
||||||
}) : undefined,
|
}) : undefined,
|
||||||
|
currentViewportIds?.length && !isSavedDialog
|
||||||
|
? callApi('fetchMessagesById', {
|
||||||
|
chat: currentChat,
|
||||||
|
messageIds: currentViewportIds,
|
||||||
|
}).catch(() => undefined)
|
||||||
|
: undefined,
|
||||||
]);
|
]);
|
||||||
global = getGlobal();
|
global = getGlobal();
|
||||||
const { chatId: newCurrentChatId } = selectCurrentMessageList(global, tabId) || {};
|
const { chatId: newCurrentChatId } = selectCurrentMessageList(global, tabId) || {};
|
||||||
@ -167,17 +192,18 @@ async function loadAndReplaceMessages<T extends GlobalState>(global: T, actions:
|
|||||||
const isDiscussionStartLoaded = !result.messages.length
|
const isDiscussionStartLoaded = !result.messages.length
|
||||||
|| result.messages.some(({ id }) => id === resultDiscussion?.firstMessageId);
|
|| result.messages.some(({ id }) => id === resultDiscussion?.firstMessageId);
|
||||||
const threadStartMessages = (isDiscussionStartLoaded && resultDiscussion?.topMessages) || [];
|
const threadStartMessages = (isDiscussionStartLoaded && resultDiscussion?.topMessages) || [];
|
||||||
const allMessages = threadStartMessages.concat(result.messages, localMessages);
|
const refreshedViewportIds = refreshedViewportMessages?.map(({ id }) => id) || [];
|
||||||
|
const allMessages = threadStartMessages.concat(result.messages, refreshedViewportMessages || [], localMessages);
|
||||||
const allMessagesWithTopicLastMessages = allMessages.concat(topicLastMessages);
|
const allMessagesWithTopicLastMessages = allMessages.concat(topicLastMessages);
|
||||||
const byId = buildCollectionByKey(allMessagesWithTopicLastMessages, 'id');
|
const byId = buildCollectionByKey(allMessagesWithTopicLastMessages, 'id');
|
||||||
const listedIds = unique(allMessages.map(({ id }) => id));
|
const listedIds = unique(refreshedViewportIds.concat(allMessages.map(({ id }) => id)));
|
||||||
|
|
||||||
if (!wasReset) {
|
if (!wasReset) {
|
||||||
global = resetMessages(global);
|
global = resetMessages(global, preservedCurrentThreadsByChatId);
|
||||||
|
|
||||||
Object.values(global.byTabId).forEach(({ id: otherTabId }) => {
|
Object.values(global.byTabId).forEach(({ id: otherTabId }) => {
|
||||||
global = updateTabState(global, {
|
global = updateTabState(global, {
|
||||||
tabThreads: {},
|
tabThreads: preservedTabThreadsByTabId[otherTabId] || {},
|
||||||
}, otherTabId);
|
}, otherTabId);
|
||||||
});
|
});
|
||||||
wasReset = true;
|
wasReset = true;
|
||||||
@ -202,7 +228,18 @@ async function loadAndReplaceMessages<T extends GlobalState>(global: T, actions:
|
|||||||
Object.values(global.byTabId).forEach(({ id: otherTabId }) => {
|
Object.values(global.byTabId).forEach(({ id: otherTabId }) => {
|
||||||
const { chatId: otherChatId, threadId: otherThreadId } = selectCurrentMessageList(global, otherTabId) || {};
|
const { chatId: otherChatId, threadId: otherThreadId } = selectCurrentMessageList(global, otherTabId) || {};
|
||||||
if (otherChatId === currentChatId && otherThreadId === activeThreadId) {
|
if (otherChatId === currentChatId && otherThreadId === activeThreadId) {
|
||||||
global = safeReplaceViewportIds(global, currentChatId, activeThreadId, listedIds, otherTabId);
|
const preservedViewportIds = preservedTabThreadsByTabId[otherTabId]
|
||||||
|
?.[currentChatId]?.[activeThreadId]?.viewportIds;
|
||||||
|
const mergedMessagesById = selectChatMessages(global, currentChatId) || {};
|
||||||
|
const nextViewportIds = preservedViewportIds?.filter((id) => Boolean(mergedMessagesById[id]));
|
||||||
|
|
||||||
|
global = safeReplaceViewportIds(
|
||||||
|
global,
|
||||||
|
currentChatId,
|
||||||
|
activeThreadId,
|
||||||
|
nextViewportIds?.length ? nextViewportIds : listedIds,
|
||||||
|
otherTabId,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
global = updateChats(global, buildCollectionByKey(result.chats, 'id'));
|
global = updateChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||||
@ -227,11 +264,11 @@ async function loadAndReplaceMessages<T extends GlobalState>(global: T, actions:
|
|||||||
global = getGlobal();
|
global = getGlobal();
|
||||||
|
|
||||||
if (!areMessagesLoaded) {
|
if (!areMessagesLoaded) {
|
||||||
global = resetMessages(global);
|
global = resetMessages(global, preservedCurrentThreadsByChatId);
|
||||||
|
|
||||||
Object.values(global.byTabId).forEach(({ id: otherTabId }) => {
|
Object.values(global.byTabId).forEach(({ id: otherTabId }) => {
|
||||||
global = updateTabState(global, {
|
global = updateTabState(global, {
|
||||||
tabThreads: {},
|
tabThreads: preservedTabThreadsByTabId[otherTabId] || {},
|
||||||
}, otherTabId);
|
}, otherTabId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -254,30 +291,124 @@ async function loadAndReplaceMessages<T extends GlobalState>(global: T, actions:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetMessages<T extends GlobalState>(global: T) {
|
function resetMessages<T extends GlobalState>(
|
||||||
|
global: T,
|
||||||
|
preservedByChatId: GlobalState['messages']['byChatId'] = {},
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
...global,
|
...global,
|
||||||
messages: {
|
messages: {
|
||||||
...global.messages,
|
...global.messages,
|
||||||
byChatId: {},
|
byChatId: preservedByChatId,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadTopMessages<T extends GlobalState>(global: T, chatId: string, threadId: ThreadId) {
|
function preserveCurrentTabThreads<T extends GlobalState>(global: T) {
|
||||||
|
return Object.values(global.byTabId).reduce<Record<number, GlobalState['byTabId'][number]['tabThreads']>>(
|
||||||
|
(acc, { id: tabId }) => {
|
||||||
|
const currentMessageList = selectCurrentMessageList(global, tabId);
|
||||||
|
if (!currentMessageList) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { chatId, threadId = MAIN_THREAD_ID } = currentMessageList;
|
||||||
|
const currentTabThread = selectTabState(global, tabId).tabThreads[chatId]?.[threadId];
|
||||||
|
|
||||||
|
if (!currentTabThread) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
acc[tabId] = {
|
||||||
|
[chatId]: {
|
||||||
|
[threadId]: currentTabThread,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function preserveCurrentThreads<T extends GlobalState>(global: T) {
|
||||||
|
return Object.values(global.byTabId).reduce<GlobalState['messages']['byChatId']>((acc, { id: tabId }) => {
|
||||||
|
const currentMessageList = selectCurrentMessageList(global, tabId);
|
||||||
|
if (!currentMessageList) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { chatId, threadId = MAIN_THREAD_ID } = currentMessageList;
|
||||||
|
const currentThread = global.messages.byChatId[chatId]?.threadsById[threadId];
|
||||||
|
if (!currentThread) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
acc[chatId] = {
|
||||||
|
byId: {},
|
||||||
|
summaryById: {},
|
||||||
|
threadsById: {
|
||||||
|
...acc[chatId]?.threadsById,
|
||||||
|
[threadId]: {
|
||||||
|
...currentThread,
|
||||||
|
localState: {
|
||||||
|
...currentThread.localState,
|
||||||
|
listedIds: undefined,
|
||||||
|
outlyingLists: undefined,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveDiscussionChat<T extends GlobalState>(
|
||||||
|
global: T,
|
||||||
|
chatId: string,
|
||||||
|
threadId: ThreadId,
|
||||||
|
) {
|
||||||
|
if (threadId === MAIN_THREAD_ID) return undefined;
|
||||||
|
|
||||||
|
const chat = selectChat(global, chatId);
|
||||||
|
if (!chat || chat.isForum || getIsSavedDialog(chatId, threadId, global.currentUserId)) return undefined;
|
||||||
|
|
||||||
|
const threadInfo = selectThreadInfo(global, chatId, threadId);
|
||||||
|
if (threadInfo?.isCommentsInfo === false && threadInfo.fromChannelId) {
|
||||||
|
const originChannel = selectChat(global, threadInfo.fromChannelId);
|
||||||
|
if (originChannel && threadInfo.fromMessageId) {
|
||||||
|
return { chat: originChannel, messageId: threadInfo.fromMessageId };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { chat, messageId: Number(threadId) };
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadTopMessages<T extends GlobalState>(
|
||||||
|
global: T,
|
||||||
|
chatId: string,
|
||||||
|
threadId: ThreadId,
|
||||||
|
viewportIds?: number[],
|
||||||
|
) {
|
||||||
const currentUserId = global.currentUserId!;
|
const currentUserId = global.currentUserId!;
|
||||||
const isSavedDialog = getIsSavedDialog(chatId, threadId, currentUserId);
|
const isSavedDialog = getIsSavedDialog(chatId, threadId, currentUserId);
|
||||||
const realChatId = isSavedDialog ? String(threadId) : chatId;
|
const realChatId = isSavedDialog ? String(threadId) : chatId;
|
||||||
|
|
||||||
const chat = selectChat(global, realChatId)!;
|
const chat = selectChat(global, realChatId);
|
||||||
|
if (!chat) return undefined;
|
||||||
|
|
||||||
const readState = selectThreadReadState(global, chatId, threadId);
|
const readState = selectThreadReadState(global, chatId, threadId);
|
||||||
|
const viewportAnchorId = viewportIds?.[0];
|
||||||
|
const shouldRestoreViewport = Boolean(viewportAnchorId && !getIsSavedDialog(chatId, threadId, currentUserId));
|
||||||
|
|
||||||
return callApi('fetchMessages', {
|
return callApi('fetchMessages', {
|
||||||
chat,
|
chat,
|
||||||
threadId,
|
threadId,
|
||||||
offsetId: !isSavedDialog ? readState?.lastReadInboxMessageId : undefined,
|
offsetId: shouldRestoreViewport ? viewportAnchorId
|
||||||
addOffset: -(Math.round(MESSAGE_LIST_SLICE / 2) + 1),
|
: (!isSavedDialog ? readState?.lastReadInboxMessageId : undefined),
|
||||||
limit: MESSAGE_LIST_SLICE,
|
addOffset: shouldRestoreViewport ? -(MESSAGE_LIST_SLICE + 1) : -(Math.round(MESSAGE_LIST_SLICE / 2) + 1),
|
||||||
|
limit: shouldRestoreViewport ? (MESSAGE_LIST_SLICE + 1) : MESSAGE_LIST_SLICE,
|
||||||
isSavedDialog,
|
isSavedDialog,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -524,6 +524,14 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'updateDiscussion': {
|
||||||
|
const { chatId, threadId } = update;
|
||||||
|
|
||||||
|
actions.loadDiscussion({ chatId, threadId });
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
case 'updateViewForumAsMessages': {
|
case 'updateViewForumAsMessages': {
|
||||||
const { chatId, isEnabled } = update;
|
const { chatId, isEnabled } = update;
|
||||||
|
|
||||||
|
|||||||
@ -3028,6 +3028,11 @@ export interface ActionPayloads {
|
|||||||
} & WithTabId;
|
} & WithTabId;
|
||||||
closeEditTopicPanel: WithTabId | undefined;
|
closeEditTopicPanel: WithTabId | undefined;
|
||||||
|
|
||||||
|
loadDiscussion: {
|
||||||
|
chatId: string;
|
||||||
|
threadId: number;
|
||||||
|
};
|
||||||
|
|
||||||
uploadContactProfilePhoto: {
|
uploadContactProfilePhoto: {
|
||||||
userId: string;
|
userId: string;
|
||||||
file?: File;
|
file?: File;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user