Comment Threads: Various fixes
This commit is contained in:
parent
d5db8639eb
commit
954ee5c508
@ -732,6 +732,7 @@ export async function requestThreadInfoUpdate({
|
|||||||
'@type': 'updateChat',
|
'@type': 'updateChat',
|
||||||
id: newChat.id,
|
id: newChat.id,
|
||||||
chat: newChat,
|
chat: newChat,
|
||||||
|
noTopChatsRequest: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,6 +61,7 @@ export type ApiUpdateChat = {
|
|||||||
id: number;
|
id: number;
|
||||||
chat: Partial<ApiChat>;
|
chat: Partial<ApiChat>;
|
||||||
newProfilePhoto?: ApiPhoto;
|
newProfilePhoto?: ApiPhoto;
|
||||||
|
noTopChatsRequest?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ApiUpdateChatJoin = {
|
export type ApiUpdateChatJoin = {
|
||||||
|
|||||||
@ -149,8 +149,7 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
const anchorIdRef = useRef<string>();
|
const anchorIdRef = useRef<string>();
|
||||||
const anchorTopRef = useRef<number>();
|
const anchorTopRef = useRef<number>();
|
||||||
const listItemElementsRef = useRef<HTMLDivElement[]>();
|
const listItemElementsRef = useRef<HTMLDivElement[]>();
|
||||||
// Updated when opening chat (to preserve divider even after messages are read)
|
const memoUnreadDividerBeforeIdRef = useRef<number | undefined>();
|
||||||
const memoUnreadDividerBeforeIdRef = useRef<number | undefined>(firstUnreadId);
|
|
||||||
// Updated every time (to be used from intersection callback closure)
|
// Updated every time (to be used from intersection callback closure)
|
||||||
const memoFirstUnreadIdRef = useRef<number>();
|
const memoFirstUnreadIdRef = useRef<number>();
|
||||||
const memoFocusingIdRef = useRef<number>();
|
const memoFocusingIdRef = useRef<number>();
|
||||||
@ -172,6 +171,11 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
|
|
||||||
useOnChange(() => {
|
useOnChange(() => {
|
||||||
memoFirstUnreadIdRef.current = firstUnreadId;
|
memoFirstUnreadIdRef.current = firstUnreadId;
|
||||||
|
|
||||||
|
// Updated only once (to preserve divider even after messages are read)
|
||||||
|
if (!memoUnreadDividerBeforeIdRef.current) {
|
||||||
|
memoUnreadDividerBeforeIdRef.current = firstUnreadId;
|
||||||
|
}
|
||||||
}, [firstUnreadId]);
|
}, [firstUnreadId]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|||||||
@ -330,7 +330,11 @@ export default memo(withGlobal(
|
|||||||
canPost: !isPinnedMessageList && (!chat || canPost) && (!isBotNotStarted || IS_MOBILE_SCREEN),
|
canPost: !isPinnedMessageList && (!chat || canPost) && (!isBotNotStarted || IS_MOBILE_SCREEN),
|
||||||
isPinnedMessageList,
|
isPinnedMessageList,
|
||||||
messageSendingRestrictionReason: chat && getMessageSendingRestrictionReason(chat),
|
messageSendingRestrictionReason: chat && getMessageSendingRestrictionReason(chat),
|
||||||
hasPinnedOrAudioMessage: Boolean(pinnedIds && pinnedIds.length) || Boolean(audioChatId && audioMessageId),
|
hasPinnedOrAudioMessage: (
|
||||||
|
threadId !== MAIN_THREAD_ID
|
||||||
|
|| Boolean(pinnedIds && pinnedIds.length)
|
||||||
|
|| Boolean(audioChatId && audioMessageId)
|
||||||
|
),
|
||||||
customBackground,
|
customBackground,
|
||||||
patternColor,
|
patternColor,
|
||||||
isCustomBackgroundColor,
|
isCustomBackgroundColor,
|
||||||
|
|||||||
@ -50,11 +50,13 @@ import {
|
|||||||
selectScheduledMessage,
|
selectScheduledMessage,
|
||||||
selectNoWebPage,
|
selectNoWebPage,
|
||||||
} from '../../selectors';
|
} from '../../selectors';
|
||||||
import { rafPromise } from '../../../util/schedulers';
|
import { rafPromise, throttle } from '../../../util/schedulers';
|
||||||
import { copyTextToClipboard } from '../../../util/clipboard';
|
import { copyTextToClipboard } from '../../../util/clipboard';
|
||||||
|
|
||||||
const uploadProgressCallbacks = new Map<number, ApiOnProgress>();
|
const uploadProgressCallbacks = new Map<number, ApiOnProgress>();
|
||||||
|
|
||||||
|
const runThrottledForMarkRead = throttle((cb) => cb(), 1000, true);
|
||||||
|
|
||||||
addReducer('loadViewportMessages', (global, actions, payload) => {
|
addReducer('loadViewportMessages', (global, actions, payload) => {
|
||||||
const {
|
const {
|
||||||
direction = LoadMoreDirection.Around,
|
direction = LoadMoreDirection.Around,
|
||||||
@ -409,7 +411,9 @@ addReducer('markMessageListRead', (global, actions, payload) => {
|
|||||||
|
|
||||||
const { maxId } = payload!;
|
const { maxId } = payload!;
|
||||||
|
|
||||||
void callApi('markMessageListRead', { chat, threadId, maxId });
|
runThrottledForMarkRead(() => {
|
||||||
|
void callApi('markMessageListRead', { chat, threadId, maxId });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
addReducer('markMessagesRead', (global, actions, payload) => {
|
addReducer('markMessagesRead', (global, actions, payload) => {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { addReducer, getGlobal, setGlobal } from '../../../lib/teact/teactn';
|
import { addReducer, getGlobal, setGlobal } from '../../../lib/teact/teactn';
|
||||||
|
|
||||||
import { ApiUpdate } from '../../../api/types';
|
import { ApiUpdate, MAIN_THREAD_ID } from '../../../api/types';
|
||||||
|
|
||||||
import { ARCHIVED_FOLDER_ID, MAX_ACTIVE_PINNED_CHATS } from '../../../config';
|
import { ARCHIVED_FOLDER_ID, MAX_ACTIVE_PINNED_CHATS } from '../../../config';
|
||||||
import { pick } from '../../../util/iteratees';
|
import { pick } from '../../../util/iteratees';
|
||||||
@ -27,7 +27,7 @@ const CURRENT_CHAT_UNREAD_DELAY = 1000;
|
|||||||
addReducer('apiUpdate', (global, actions, update: ApiUpdate) => {
|
addReducer('apiUpdate', (global, actions, update: ApiUpdate) => {
|
||||||
switch (update['@type']) {
|
switch (update['@type']) {
|
||||||
case 'updateChat': {
|
case 'updateChat': {
|
||||||
if (!selectIsChatListed(global, update.id)) {
|
if (!update.noTopChatsRequest && !selectIsChatListed(global, update.id)) {
|
||||||
// Chat can appear in dialogs list.
|
// Chat can appear in dialogs list.
|
||||||
actions.loadTopChats();
|
actions.loadTopChats();
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ addReducer('apiUpdate', (global, actions, update: ApiUpdate) => {
|
|||||||
|
|
||||||
case 'newMessage': {
|
case 'newMessage': {
|
||||||
const { message } = update;
|
const { message } = update;
|
||||||
const { chatId: currentChatId } = selectCurrentMessageList(global) || {};
|
const { chatId: currentChatId, threadId, type: messageListType } = selectCurrentMessageList(global) || {};
|
||||||
|
|
||||||
if (message.senderId === global.currentUserId && !message.isFromScheduled) {
|
if (message.senderId === global.currentUserId && !message.isFromScheduled) {
|
||||||
return;
|
return;
|
||||||
@ -106,7 +106,11 @@ addReducer('apiUpdate', (global, actions, update: ApiUpdate) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isActiveChat = update.chatId === currentChatId;
|
const isActiveChat = (
|
||||||
|
messageListType === 'thread'
|
||||||
|
&& threadId === MAIN_THREAD_ID
|
||||||
|
&& update.chatId === currentChatId
|
||||||
|
);
|
||||||
|
|
||||||
if (isActiveChat) {
|
if (isActiveChat) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|||||||
@ -494,9 +494,7 @@ export function selectRealLastReadId(global: GlobalState, chatId: number, thread
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Some previously read messages may be deleted
|
// Some previously read messages may be deleted
|
||||||
return threadInfo.lastMessageId
|
return Math.min(threadInfo.lastReadInboxMessageId, threadInfo.lastMessageId || Infinity);
|
||||||
? Math.min(threadInfo.lastReadInboxMessageId, threadInfo.lastMessageId)
|
|
||||||
: threadInfo.lastReadInboxMessageId;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user