Comments: Fix focus on top message (#3356)
This commit is contained in:
parent
86f8ad9e2f
commit
915dbe5736
@ -36,7 +36,6 @@ import {
|
||||
selectIsChatBotNotStarted,
|
||||
selectScrollOffset,
|
||||
selectThreadTopMessageId,
|
||||
selectFirstMessageId,
|
||||
selectChatScheduledMessages,
|
||||
selectCurrentMessageIds,
|
||||
selectIsCurrentUserPremium,
|
||||
@ -127,7 +126,6 @@ type StateProps = {
|
||||
isLoadingBotInfo?: boolean;
|
||||
botInfo?: ApiBotInfo;
|
||||
threadTopMessageId?: number;
|
||||
threadFirstMessageId?: number;
|
||||
hasLinkedChat?: boolean;
|
||||
lastSyncTime?: number;
|
||||
topic?: ApiTopic;
|
||||
@ -170,7 +168,6 @@ const MessageList: FC<OwnProps & StateProps> = ({
|
||||
firstUnreadId,
|
||||
isComments,
|
||||
isViewportNewest,
|
||||
threadFirstMessageId,
|
||||
isRestricted,
|
||||
restrictionReason,
|
||||
focusingId,
|
||||
@ -259,23 +256,11 @@ const MessageList: FC<OwnProps & StateProps> = ({
|
||||
useNativeCopySelectedMessages(copyMessagesByIds);
|
||||
|
||||
const messageGroups = useMemo(() => {
|
||||
if (!messageIds || !messagesById) {
|
||||
if (!messageIds?.length || !messagesById) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const viewportIds = (
|
||||
threadTopMessageId
|
||||
&& threadFirstMessageId !== threadTopMessageId
|
||||
&& (!messageIds[0] || threadFirstMessageId === messageIds[0])
|
||||
)
|
||||
? [threadTopMessageId, ...messageIds]
|
||||
: messageIds;
|
||||
|
||||
if (!viewportIds.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const listedMessages = viewportIds.map((id) => messagesById[id]).filter(Boolean);
|
||||
const listedMessages = messageIds.map((id) => messagesById[id]).filter(Boolean);
|
||||
|
||||
// Service notifications have local IDs which may be not in sync with real message history
|
||||
const orderRule: (keyof ApiMessage)[] = type === 'scheduled' || isServiceNotificationsChat
|
||||
@ -285,7 +270,7 @@ const MessageList: FC<OwnProps & StateProps> = ({
|
||||
return listedMessages.length
|
||||
? groupMessages(orderBy(listedMessages, orderRule), memoUnreadDividerBeforeIdRef.current)
|
||||
: undefined;
|
||||
}, [messageIds, messagesById, threadFirstMessageId, threadTopMessageId, type, isServiceNotificationsChat]);
|
||||
}, [messageIds, messagesById, type, isServiceNotificationsChat]);
|
||||
|
||||
useInterval(() => {
|
||||
if (!messageIds || !messagesById || type === 'scheduled') {
|
||||
@ -746,7 +731,6 @@ export default memo(withGlobal<OwnProps>(
|
||||
isComments: Boolean(threadInfo?.originChannelId),
|
||||
firstUnreadId: selectFirstUnreadId(global, chatId, threadId),
|
||||
isViewportNewest: type !== 'thread' || selectIsViewportNewest(global, chatId, threadId),
|
||||
threadFirstMessageId: selectFirstMessageId(global, chatId, threadId),
|
||||
focusingId,
|
||||
isSelectModeActive: selectIsInSelectMode(global),
|
||||
isLoadingBotInfo,
|
||||
|
||||
@ -45,7 +45,7 @@ import {
|
||||
selectReplyingToId,
|
||||
selectTabState,
|
||||
selectTheme,
|
||||
selectThreadInfo,
|
||||
selectThreadInfo, selectThreadTopMessageId,
|
||||
} from '../../global/selectors';
|
||||
import {
|
||||
getCanPostInChat,
|
||||
@ -140,6 +140,7 @@ type StateProps = {
|
||||
shouldSendJoinRequest?: boolean;
|
||||
lastSyncTime?: number;
|
||||
pinnedIds?: number[];
|
||||
topMessageId?: number;
|
||||
};
|
||||
|
||||
function isImage(item: DataTransferItem) {
|
||||
@ -193,6 +194,7 @@ function MiddleColumn({
|
||||
shouldLoadFullChat,
|
||||
lastSyncTime,
|
||||
pinnedIds,
|
||||
topMessageId,
|
||||
}: OwnProps & StateProps) {
|
||||
const {
|
||||
openChat,
|
||||
@ -226,7 +228,7 @@ function MiddleColumn({
|
||||
getCurrentPinnedIndexes,
|
||||
getLoadingPinnedId,
|
||||
getForceNextPinnedInHeader,
|
||||
} = usePinnedMessage(chatId, threadId, pinnedIds);
|
||||
} = usePinnedMessage(chatId, threadId, pinnedIds, topMessageId);
|
||||
|
||||
const isMobileSearchActive = isMobile && hasCurrentTextSearch;
|
||||
const closeAnimationDuration = isMobile ? LAYER_ANIMATION_DURATION_MS : undefined;
|
||||
@ -720,6 +722,9 @@ export default memo(withGlobal<OwnProps>(
|
||||
? selectChatMessage(global, audioChatId, audioMessageId)
|
||||
: undefined;
|
||||
|
||||
const isCommentThread = threadId !== MAIN_THREAD_ID && !chat?.isForum;
|
||||
const topMessageId = isCommentThread ? selectThreadTopMessageId(global, chatId, threadId) : undefined;
|
||||
|
||||
return {
|
||||
...state,
|
||||
chatId,
|
||||
@ -737,10 +742,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
isPinnedMessageList,
|
||||
currentUserBannedRights: chat?.currentUserBannedRights,
|
||||
defaultBannedRights: chat?.defaultBannedRights,
|
||||
hasPinned: (
|
||||
(threadId !== MAIN_THREAD_ID && !chat?.isForum)
|
||||
|| Boolean(!isPinnedMessageList && pinnedIds?.length)
|
||||
),
|
||||
hasPinned: isCommentThread || Boolean(!isPinnedMessageList && pinnedIds?.length),
|
||||
hasAudioPlayer: Boolean(audioMessage),
|
||||
hasButtonInHeader: canStartBot || canRestartBot || canSubscribe || shouldSendJoinRequest,
|
||||
pinnedMessagesCount: pinnedIds ? pinnedIds.length : 0,
|
||||
@ -753,6 +755,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
shouldSendJoinRequest,
|
||||
shouldLoadFullChat,
|
||||
pinnedIds,
|
||||
topMessageId,
|
||||
};
|
||||
},
|
||||
)(MiddleColumn));
|
||||
|
||||
@ -23,7 +23,9 @@ type PinnedIntersectionChangedParams = {
|
||||
|
||||
export type PinnedIntersectionChangedCallback = (params: PinnedIntersectionChangedParams) => void;
|
||||
|
||||
export default function usePinnedMessage(chatId?: string, threadId?: number, pinnedIds?: number[]) {
|
||||
export default function usePinnedMessage(
|
||||
chatId?: string, threadId?: number, pinnedIds?: number[], topMessageId?: number,
|
||||
) {
|
||||
const [getCurrentPinnedIndexes, setCurrentPinnedIndexes] = useSignal<Record<string, number>>({});
|
||||
const [getForceNextPinnedInHeader, setForceNextPinnedInHeader] = useSignal<boolean | undefined>();
|
||||
const viewportPinnedIdsRef = useRef<number[] | undefined>();
|
||||
@ -133,7 +135,10 @@ export default function usePinnedMessage(chatId?: string, threadId?: number, pin
|
||||
if (!chatId || !threadId || !key || getLoadingPinnedId()) return false;
|
||||
|
||||
const global = getGlobal();
|
||||
if (!pinnedIds?.length) return false;
|
||||
if (!pinnedIds?.length) {
|
||||
// Focusing on a post in comments
|
||||
return topMessageId === messageId;
|
||||
}
|
||||
|
||||
const index = pinnedIds.indexOf(messageId);
|
||||
const newPinnedIndex = cycleRestrict(pinnedIds.length, index + 1);
|
||||
|
||||
@ -68,7 +68,7 @@ import {
|
||||
selectDraft,
|
||||
selectEditingId,
|
||||
selectEditingMessage,
|
||||
selectEditingScheduledId,
|
||||
selectEditingScheduledId, selectFirstMessageId,
|
||||
selectFirstUnreadId,
|
||||
selectFocusedMessageId,
|
||||
selectForwardsCanBeSentToChat,
|
||||
@ -1020,6 +1020,12 @@ async function loadViewportMessages<T extends GlobalState>(
|
||||
const allMessages = ([] as ApiMessage[]).concat(messages, localMessages);
|
||||
const byId = buildCollectionByKey(allMessages, 'id');
|
||||
const ids = Object.keys(byId).map(Number);
|
||||
const threadFirstMessageId = selectFirstMessageId(global, chatId, threadId) || {};
|
||||
if (threadId
|
||||
&& threadFirstMessageId !== threadId
|
||||
&& (!ids[0] || threadFirstMessageId === ids[0])) {
|
||||
ids.unshift(threadId);
|
||||
}
|
||||
|
||||
global = addChatMessagesById(global, chatId, byId);
|
||||
global = isOutlying
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user