Message List: Reply focusing stack (#1260)
This commit is contained in:
parent
fa8e750433
commit
e744febfe8
@ -27,7 +27,7 @@ type StateProps = {
|
||||
unreadCount?: number;
|
||||
};
|
||||
|
||||
type DispatchProps = Pick<GlobalActions, 'focusLastMessage'>;
|
||||
type DispatchProps = Pick<GlobalActions, 'focusNextReply'>;
|
||||
|
||||
const FOCUS_MARGIN = 20;
|
||||
|
||||
@ -36,7 +36,7 @@ const ScrollDownButton: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
canPost,
|
||||
messageListType,
|
||||
unreadCount,
|
||||
focusLastMessage,
|
||||
focusNextReply,
|
||||
}) => {
|
||||
const lang = useLang();
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
@ -48,7 +48,7 @@ const ScrollDownButton: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
}
|
||||
|
||||
if (messageListType === 'thread') {
|
||||
focusLastMessage();
|
||||
focusNextReply();
|
||||
} else {
|
||||
const messagesContainer = elementRef.current!.parentElement!.querySelector<HTMLDivElement>('.MessageList')!;
|
||||
const messageElements = messagesContainer.querySelectorAll<HTMLDivElement>('.message-list-item');
|
||||
@ -59,7 +59,7 @@ const ScrollDownButton: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
|
||||
fastSmoothScroll(messagesContainer, lastMessageElement, 'end', FOCUS_MARGIN);
|
||||
}
|
||||
}, [isShown, messageListType, focusLastMessage]);
|
||||
}, [isShown, messageListType, focusNextReply]);
|
||||
|
||||
const fabClassName = buildClassName(
|
||||
'ScrollDownButton',
|
||||
@ -101,5 +101,5 @@ export default memo(withGlobal<OwnProps>(
|
||||
unreadCount: chat && threadId === MAIN_THREAD_ID && messageListType === 'thread' ? chat.unreadCount : undefined,
|
||||
};
|
||||
},
|
||||
(setGlobal, actions): DispatchProps => pick(actions, ['focusLastMessage']),
|
||||
(setGlobal, actions): DispatchProps => pick(actions, ['focusNextReply']),
|
||||
)(ScrollDownButton));
|
||||
|
||||
@ -416,8 +416,10 @@ const Message: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
}, [botSender, openUserInfo]);
|
||||
|
||||
const handleReplyClick = useCallback((): void => {
|
||||
focusMessage({ chatId, threadId, messageId: message.replyToMessageId });
|
||||
}, [focusMessage, chatId, threadId, message.replyToMessageId]);
|
||||
focusMessage({
|
||||
chatId, threadId, messageId: message.replyToMessageId, replyMessageId: messageId,
|
||||
});
|
||||
}, [focusMessage, chatId, threadId, message.replyToMessageId, messageId]);
|
||||
|
||||
const handleMediaClick = useCallback((): void => {
|
||||
openMediaViewer({
|
||||
|
||||
@ -58,6 +58,7 @@ export interface Thread {
|
||||
noWebPage?: boolean;
|
||||
threadInfo?: ApiThreadInfo;
|
||||
firstMessageId?: number;
|
||||
replyStack?: number[];
|
||||
}
|
||||
|
||||
export type GlobalState = {
|
||||
@ -424,7 +425,7 @@ export type ActionTypes = (
|
||||
'openTelegramLink' | 'openChatByUsername' | 'requestThreadInfoUpdate' | 'setScrollOffset' | 'unpinAllMessages' |
|
||||
'setReplyingToId' | 'setEditingId' | 'editLastMessage' | 'saveDraft' | 'clearDraft' | 'loadPinnedMessages' |
|
||||
'loadMessageLink' | 'toggleMessageWebPage' | 'replyToNextMessage' | 'deleteChatUser' | 'deleteChat' |
|
||||
'reportMessages' |
|
||||
'reportMessages' | 'focusNextReply' |
|
||||
// scheduled messages
|
||||
'loadScheduledHistory' | 'sendScheduledMessages' | 'rescheduleMessage' | 'deleteScheduledMessages' |
|
||||
// poll result
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { addReducer, setGlobal } from '../../../lib/teact/teactn';
|
||||
import {
|
||||
exitMessageSelectMode,
|
||||
updateCurrentMessageList,
|
||||
exitMessageSelectMode, replaceThreadParam, updateCurrentMessageList,
|
||||
} from '../../reducers';
|
||||
import { selectCurrentMessageList } from '../../selectors';
|
||||
import { closeLocalTextSearch } from './localSearch';
|
||||
@ -19,6 +18,7 @@ addReducer('openChat', (global, actions, payload) => {
|
||||
|| currentMessageList.threadId !== threadId
|
||||
|| currentMessageList.type !== type
|
||||
)) {
|
||||
global = replaceThreadParam(global, id, threadId, 'replyStack', []);
|
||||
global = exitMessageSelectMode(global);
|
||||
global = closeLocalTextSearch(global);
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ import {
|
||||
selectChatMessages,
|
||||
selectAllowedMessageActions,
|
||||
selectMessageIdsByGroupId,
|
||||
selectForwardedMessageIdsByGroupId, selectIsViewportNewest, selectReplyingToId,
|
||||
selectForwardedMessageIdsByGroupId, selectIsViewportNewest, selectReplyingToId, selectReplyStack,
|
||||
} from '../../selectors';
|
||||
import { findLast } from '../../../util/iteratees';
|
||||
import { IS_TOUCH_ENV } from '../../../util/environment';
|
||||
@ -240,9 +240,39 @@ addReducer('focusLastMessage', (global, actions) => {
|
||||
});
|
||||
});
|
||||
|
||||
addReducer('focusNextReply', (global, actions) => {
|
||||
const currentMessageList = selectCurrentMessageList(global);
|
||||
if (!currentMessageList) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const { chatId, threadId } = currentMessageList;
|
||||
|
||||
const replyStack = selectReplyStack(global, chatId, threadId);
|
||||
|
||||
if (!replyStack || replyStack.length === 0) {
|
||||
actions.focusLastMessage();
|
||||
} else {
|
||||
const messageId = replyStack.pop();
|
||||
|
||||
global = replaceThreadParam(global, chatId, threadId, 'replyStack', [...replyStack]);
|
||||
|
||||
setGlobal(global);
|
||||
|
||||
actions.focusMessage({
|
||||
chatId,
|
||||
threadId,
|
||||
messageId,
|
||||
});
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
|
||||
addReducer('focusMessage', (global, actions, payload) => {
|
||||
const {
|
||||
chatId, threadId = MAIN_THREAD_ID, messageListType = 'thread', noHighlight, groupedId, groupedChatId,
|
||||
replyMessageId,
|
||||
} = payload!;
|
||||
|
||||
let { messageId } = payload!;
|
||||
@ -275,6 +305,11 @@ addReducer('focusMessage', (global, actions, payload) => {
|
||||
global = updateFocusedMessage(global, chatId, messageId, noHighlight);
|
||||
global = updateFocusDirection(global, undefined);
|
||||
|
||||
if (replyMessageId) {
|
||||
const replyStack = selectReplyStack(global, chatId, threadId) || [];
|
||||
global = replaceThreadParam(global, chatId, threadId, 'replyStack', [...replyStack, replyMessageId]);
|
||||
}
|
||||
|
||||
if (shouldSwitchChat) {
|
||||
global = updateFocusDirection(global, FocusDirection.Static);
|
||||
}
|
||||
|
||||
@ -150,6 +150,10 @@ export function selectFirstMessageId(global: GlobalState, chatId: number, thread
|
||||
return selectThreadParam(global, chatId, threadId, 'firstMessageId');
|
||||
}
|
||||
|
||||
export function selectReplyStack(global: GlobalState, chatId: number, threadId: number) {
|
||||
return selectThreadParam(global, chatId, threadId, 'replyStack');
|
||||
}
|
||||
|
||||
export function selectThreadOriginChat(global: GlobalState, chatId: number, threadId: number) {
|
||||
if (threadId === MAIN_THREAD_ID) {
|
||||
return selectChat(global, chatId);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user