Fix chat flicker / Usernames collapse in order (#3135)

Co-authored-by: janWilejan <>
This commit is contained in:
janWilejan 2023-07-05 18:51:16 +00:00 committed by GitHub
parent 9b450ec64b
commit 74ad8d5e18
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -32,49 +32,33 @@ export type ChatContainerProps = {
focusInput?: boolean; focusInput?: boolean;
}; };
function shouldCollapseMessages( function shouldCollapseMessages(message: ChatMessage, previous: ChatMessage): boolean {
messages: ChatMessage[], if (!message || !message.user) {
index: number,
collapsedMessageIds: Set<string>,
): boolean {
if (messages.length < 2) {
return false; return false;
} }
const message = messages[index]; if (previous.type !== MessageType.CHAT) {
if (!message || !message.user) {
return false; return false;
} }
const { const {
user: { id }, user: { id },
} = message; } = message;
const lastMessage = messages[index - 1]; if (id !== previous.user.id) {
if (lastMessage?.type !== MessageType.CHAT) {
return false; return false;
} }
if (!lastMessage?.timestamp || !message.timestamp) { if (!previous.timestamp || !message.timestamp) {
return false; return false;
} }
const maxTimestampDelta = 1000 * 40; // 40 seconds const maxTimestampDelta = 1000 * 40; // 40 seconds
const lastTimestamp = new Date(lastMessage?.timestamp).getTime(); const lastTimestamp = new Date(previous.timestamp).getTime();
const thisTimestamp = new Date(message.timestamp).getTime(); const thisTimestamp = new Date(message.timestamp).getTime();
if (thisTimestamp - lastTimestamp > maxTimestampDelta) { if (thisTimestamp - lastTimestamp > maxTimestampDelta) {
return false; return false;
} }
if (id !== lastMessage?.user.id) {
return false;
}
// Limit the number of messages that can be collapsed in a row.
const maxCollapsedMessageCount = 5;
if (collapsedMessageIds.size >= maxCollapsedMessageCount) {
return false;
}
return true; return true;
} }
@ -101,7 +85,28 @@ export const ChatContainer: FC<ChatContainerProps> = ({
const chatContainerRef = useRef(null); const chatContainerRef = useRef(null);
const scrollToBottomDelay = useRef(null); const scrollToBottomDelay = useRef(null);
const collapsedMessageIds = new Set<string>(); const collapsedIndexes: boolean[] = [];
let consecutiveTally: number = 1;
function calculateCollapsedMessages() {
// Limits the number of messages that can be collapsed in a row.
const maxCollapsedMessageCount = 5;
for (let i = collapsedIndexes.length; i < messages.length; i += 1) {
const collapse: boolean =
i > 0 &&
consecutiveTally < maxCollapsedMessageCount &&
shouldCollapseMessages(messages[i], messages[i - 1]);
collapsedIndexes.push(collapse);
consecutiveTally = 1 + (collapse ? consecutiveTally : 0);
}
}
function shouldCollapse(index: number): boolean {
if (collapsedIndexes.length <= index) {
calculateCollapsedMessages();
}
return collapsedIndexes[index];
}
useEffect( useEffect(
() => () =>
@ -147,13 +152,6 @@ export const ChatContainer: FC<ChatContainerProps> = ({
}; };
const getUserChatMessageView = (index: number, message: ChatMessage) => { const getUserChatMessageView = (index: number, message: ChatMessage) => {
const collapsed = shouldCollapseMessages(messages, index, collapsedMessageIds);
if (!collapsed) {
collapsedMessageIds.clear();
} else {
collapsedMessageIds.add(message.id);
}
const isAuthorModerator = checkIsModerator(message); const isAuthorModerator = checkIsModerator(message);
return ( return (
@ -162,7 +160,7 @@ export const ChatContainer: FC<ChatContainerProps> = ({
showModeratorMenu={isModerator} // Moderators have access to an additional menu showModeratorMenu={isModerator} // Moderators have access to an additional menu
highlightString={usernameToHighlight} // What to highlight in the message highlightString={usernameToHighlight} // What to highlight in the message
sentBySelf={message.user?.id === chatUserId} // The local user sent this message sentBySelf={message.user?.id === chatUserId} // The local user sent this message
sameUserAsLast={collapsed} sameUserAsLast={shouldCollapse(index)}
isAuthorModerator={isAuthorModerator} isAuthorModerator={isAuthorModerator}
isAuthorBot={message.user?.isBot} isAuthorBot={message.user?.isBot}
isAuthorAuthenticated={message.user?.authenticated} isAuthorAuthenticated={message.user?.authenticated}