Message List: Fix double focusing
This commit is contained in:
parent
55dbc323aa
commit
fc919a0c4c
@ -9,6 +9,7 @@ import type {
|
|||||||
} from '../../api/types';
|
} from '../../api/types';
|
||||||
import type { FocusDirection } from '../../types';
|
import type { FocusDirection } from '../../types';
|
||||||
import type { PinnedIntersectionChangedCallback } from './hooks/usePinnedMessage';
|
import type { PinnedIntersectionChangedCallback } from './hooks/usePinnedMessage';
|
||||||
|
import type { MessageListType } from '../../global/types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
selectUser,
|
selectUser,
|
||||||
@ -17,6 +18,7 @@ import {
|
|||||||
selectChat,
|
selectChat,
|
||||||
selectTopicFromMessage,
|
selectTopicFromMessage,
|
||||||
selectTabState,
|
selectTabState,
|
||||||
|
selectCurrentMessageIds,
|
||||||
} from '../../global/selectors';
|
} from '../../global/selectors';
|
||||||
import { getMessageHtmlId, isChatChannel } from '../../global/helpers';
|
import { getMessageHtmlId, isChatChannel } from '../../global/helpers';
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
@ -38,6 +40,7 @@ import ActionMessageSuggestedAvatar from './ActionMessageSuggestedAvatar';
|
|||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
message: ApiMessage;
|
message: ApiMessage;
|
||||||
threadId?: number;
|
threadId?: number;
|
||||||
|
messageListType?: MessageListType;
|
||||||
observeIntersectionForReading?: ObserveFn;
|
observeIntersectionForReading?: ObserveFn;
|
||||||
observeIntersectionForLoading?: ObserveFn;
|
observeIntersectionForLoading?: ObserveFn;
|
||||||
observeIntersectionForPlaying?: ObserveFn;
|
observeIntersectionForPlaying?: ObserveFn;
|
||||||
@ -60,6 +63,7 @@ type StateProps = {
|
|||||||
topic?: ApiTopic;
|
topic?: ApiTopic;
|
||||||
focusDirection?: FocusDirection;
|
focusDirection?: FocusDirection;
|
||||||
noFocusHighlight?: boolean;
|
noFocusHighlight?: boolean;
|
||||||
|
viewportIds?: number[];
|
||||||
premiumGiftSticker?: ApiSticker;
|
premiumGiftSticker?: ApiSticker;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -79,6 +83,7 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
|
|||||||
isFocused,
|
isFocused,
|
||||||
focusDirection,
|
focusDirection,
|
||||||
noFocusHighlight,
|
noFocusHighlight,
|
||||||
|
viewportIds,
|
||||||
premiumGiftSticker,
|
premiumGiftSticker,
|
||||||
isInsideTopic,
|
isInsideTopic,
|
||||||
topic,
|
topic,
|
||||||
@ -97,7 +102,7 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
useOnIntersect(ref, observeIntersectionForReading);
|
useOnIntersect(ref, observeIntersectionForReading);
|
||||||
useEnsureMessage(message.chatId, message.replyToMessageId, targetMessage);
|
useEnsureMessage(message.chatId, message.replyToMessageId, targetMessage);
|
||||||
useFocusMessage(ref, message.chatId, isFocused, focusDirection, noFocusHighlight);
|
useFocusMessage(ref, message.id, message.chatId, isFocused, focusDirection, noFocusHighlight, viewportIds);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!message.isPinned) return undefined;
|
if (!message.isPinned) return undefined;
|
||||||
@ -247,13 +252,17 @@ const ActionMessage: FC<OwnProps & StateProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default memo(withGlobal<OwnProps>(
|
export default memo(withGlobal<OwnProps>(
|
||||||
(global, { message, threadId }): StateProps => {
|
(global, { message, threadId, messageListType }): StateProps => {
|
||||||
|
const {
|
||||||
|
chatId, senderId, replyToMessageId, content,
|
||||||
|
} = message;
|
||||||
|
|
||||||
const { byId: usersById } = global.users;
|
const { byId: usersById } = global.users;
|
||||||
const userId = message.senderId;
|
const userId = senderId;
|
||||||
const { targetUserIds, targetChatId } = message.content.action || {};
|
const { targetUserIds, targetChatId } = content.action || {};
|
||||||
const targetMessageId = message.replyToMessageId;
|
const targetMessageId = replyToMessageId;
|
||||||
const targetMessage = targetMessageId
|
const targetMessage = targetMessageId
|
||||||
? selectChatMessage(global, message.chatId, targetMessageId)
|
? selectChatMessage(global, chatId, targetMessageId)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const isFocused = threadId ? selectIsMessageFocused(global, message, threadId) : false;
|
const isFocused = threadId ? selectIsMessageFocused(global, message, threadId) : false;
|
||||||
@ -262,8 +271,8 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
noHighlight: noFocusHighlight,
|
noHighlight: noFocusHighlight,
|
||||||
} = (isFocused && selectTabState(global).focusedMessage) || {};
|
} = (isFocused && selectTabState(global).focusedMessage) || {};
|
||||||
|
|
||||||
const chat = selectChat(global, message.chatId);
|
const chat = selectChat(global, chatId);
|
||||||
const isChat = chat && (isChatChannel(chat) || userId === message.chatId);
|
const isChat = chat && (isChatChannel(chat) || userId === chatId);
|
||||||
const senderUser = !isChat && userId ? selectUser(global, userId) : undefined;
|
const senderUser = !isChat && userId ? selectUser(global, userId) : undefined;
|
||||||
const senderChat = isChat ? chat : undefined;
|
const senderChat = isChat ? chat : undefined;
|
||||||
const premiumGiftSticker = global.premiumGifts?.stickers?.[0];
|
const premiumGiftSticker = global.premiumGifts?.stickers?.[0];
|
||||||
@ -279,7 +288,13 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
isFocused,
|
isFocused,
|
||||||
premiumGiftSticker,
|
premiumGiftSticker,
|
||||||
topic,
|
topic,
|
||||||
...(isFocused && { focusDirection, noFocusHighlight }),
|
...(isFocused && {
|
||||||
|
focusDirection,
|
||||||
|
noFocusHighlight,
|
||||||
|
viewportIds: threadId && messageListType
|
||||||
|
? selectCurrentMessageIds(global, chatId, threadId, messageListType)
|
||||||
|
: undefined,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(ActionMessage));
|
)(ActionMessage));
|
||||||
|
|||||||
@ -150,6 +150,7 @@ const MessageListContent: FC<OwnProps> = ({
|
|||||||
key={message.id}
|
key={message.id}
|
||||||
message={message}
|
message={message}
|
||||||
threadId={threadId}
|
threadId={threadId}
|
||||||
|
messageListType={type}
|
||||||
isInsideTopic={Boolean(threadId && threadId !== MAIN_THREAD_ID)}
|
isInsideTopic={Boolean(threadId && threadId !== MAIN_THREAD_ID)}
|
||||||
observeIntersectionForReading={observeIntersectionForReading}
|
observeIntersectionForReading={observeIntersectionForReading}
|
||||||
observeIntersectionForLoading={observeIntersectionForLoading}
|
observeIntersectionForLoading={observeIntersectionForLoading}
|
||||||
|
|||||||
@ -647,7 +647,10 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
replyMessage,
|
replyMessage,
|
||||||
message.id,
|
message.id,
|
||||||
);
|
);
|
||||||
useFocusMessage(ref, chatId, isFocused, focusDirection, noFocusHighlight, isResizingContainer, viewportIds);
|
|
||||||
|
useFocusMessage(
|
||||||
|
ref, messageId, chatId, isFocused, focusDirection, noFocusHighlight, viewportIds, isResizingContainer,
|
||||||
|
);
|
||||||
|
|
||||||
const shouldFocusOnResize = isLastInGroup;
|
const shouldFocusOnResize = isLastInGroup;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import type { FocusDirection } from '../../../../types';
|
import type { FocusDirection } from '../../../../types';
|
||||||
|
|
||||||
import { useLayoutEffect } from '../../../../lib/teact/teact';
|
import { useLayoutEffect, useMemo } from '../../../../lib/teact/teact';
|
||||||
import fastSmoothScroll from '../../../../util/fastSmoothScroll';
|
import fastSmoothScroll from '../../../../util/fastSmoothScroll';
|
||||||
|
|
||||||
// This is used when the viewport was replaced.
|
// This is used when the viewport was replaced.
|
||||||
@ -9,13 +9,23 @@ const FOCUS_MARGIN = 20;
|
|||||||
|
|
||||||
export default function useFocusMessage(
|
export default function useFocusMessage(
|
||||||
elementRef: { current: HTMLDivElement | null },
|
elementRef: { current: HTMLDivElement | null },
|
||||||
|
messageId: number,
|
||||||
chatId: string,
|
chatId: string,
|
||||||
isFocused?: boolean,
|
isFocused?: boolean,
|
||||||
focusDirection?: FocusDirection,
|
focusDirection?: FocusDirection,
|
||||||
noFocusHighlight?: boolean,
|
noFocusHighlight?: boolean,
|
||||||
isResizingContainer?: boolean,
|
|
||||||
viewportIds?: number[],
|
viewportIds?: number[],
|
||||||
|
isResizingContainer?: boolean,
|
||||||
) {
|
) {
|
||||||
|
const viewportIndex = useMemo(() => {
|
||||||
|
if (!viewportIds) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const index = viewportIds.indexOf(messageId);
|
||||||
|
return Math.min(index, viewportIds.length - index - 1);
|
||||||
|
}, [messageId, viewportIds]);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (isFocused && elementRef.current) {
|
if (isFocused && elementRef.current) {
|
||||||
const messagesContainer = elementRef.current.closest<HTMLDivElement>('.MessageList')!;
|
const messagesContainer = elementRef.current.closest<HTMLDivElement>('.MessageList')!;
|
||||||
@ -33,6 +43,6 @@ export default function useFocusMessage(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
elementRef, chatId, isFocused, focusDirection, noFocusHighlight, isResizingContainer, viewportIds,
|
elementRef, chatId, isFocused, focusDirection, noFocusHighlight, isResizingContainer, viewportIndex,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user