Forward Recipient Picker: Fix forwarding messages when reply exists (#4615)

This commit is contained in:
Alexander Zinchuk 2024-06-12 18:11:02 +02:00
parent 28f48340e8
commit 8a7d6f8c07
5 changed files with 50 additions and 55 deletions

View File

@ -1012,7 +1012,7 @@ const Composer: FC<OwnProps & StateProps> = ({
lastMessageSendTimeSeconds.current = getServerTime();
clearDraft({ chatId, isLocalOnly: true });
clearDraft({ chatId, isLocalOnly: true, shouldKeepReply: isForwarding });
if (IS_IOS && messageInput && messageInput === document.activeElement) {
applyIosAutoCapitalizationFix(messageInput);

View File

@ -5,13 +5,10 @@ import React, {
import { getActions, getGlobal, withGlobal } from '../../global';
import type { ThreadId } from '../../types';
import { MAIN_THREAD_ID } from '../../api/types';
import { getChatTitle, getUserFirstOrLastName, isUserId } from '../../global/helpers';
import {
selectChat,
selectCurrentChat,
selectDraft,
selectTabState,
selectUser,
} from '../../global/selectors';
@ -30,7 +27,7 @@ interface StateProps {
currentUserId?: string;
isManyMessages?: boolean;
isStory?: boolean;
isReplying?: boolean;
isForwarding?: boolean;
}
const ForwardRecipientPicker: FC<OwnProps & StateProps> = ({
@ -38,7 +35,7 @@ const ForwardRecipientPicker: FC<OwnProps & StateProps> = ({
currentUserId,
isManyMessages,
isStory,
isReplying,
isForwarding,
}) => {
const {
openChatOrTopicWithReplyInDraft,
@ -96,13 +93,13 @@ const ForwardRecipientPicker: FC<OwnProps & StateProps> = ({
} else {
const chatId = recipientId;
const topicId = threadId ? Number(threadId) : undefined;
if (isReplying) {
openChatOrTopicWithReplyInDraft({ chatId, topicId });
} else {
if (isForwarding) {
setForwardChatOrTopic({ chatId, topicId });
} else {
openChatOrTopicWithReplyInDraft({ chatId, topicId });
}
}
}, [currentUserId, isManyMessages, isStory, lang, isReplying]);
}, [currentUserId, isManyMessages, isStory, lang, isForwarding]);
const handleClose = useCallback(() => {
exitForwardMode();
@ -126,12 +123,11 @@ const ForwardRecipientPicker: FC<OwnProps & StateProps> = ({
export default memo(withGlobal<OwnProps>((global): StateProps => {
const { messageIds, storyId } = selectTabState(global).forwardMessages;
const currentChatId = selectCurrentChat(global)?.id;
const isReplying = currentChatId && selectDraft(global, currentChatId, MAIN_THREAD_ID)?.replyInfo;
const isForwarding = (messageIds && messageIds.length > 0);
return {
currentUserId: global.currentUserId,
isManyMessages: (messageIds?.length || 0) > 1,
isStory: Boolean(storyId),
isReplying: Boolean(isReplying),
isForwarding,
};
})(ForwardRecipientPicker));

View File

@ -116,8 +116,8 @@ const ComposerEmbeddedMessage: FC<OwnProps & StateProps> = ({
const isShown = (() => {
if (isInChangingRecipientMode) return false;
if (sender && isForwarding) return true;
if (message && (replyInfo || editingId)) return true;
if (sender && isForwarding) return true;
return false;
})();
@ -139,12 +139,12 @@ const ComposerEmbeddedMessage: FC<OwnProps & StateProps> = ({
});
const clearEmbedded = useLastCallback(() => {
if (replyInfo && !shouldForceShowEditing) {
resetDraftReplyInfo();
} else if (editingId) {
if (editingId) {
setEditingId({ messageId: undefined });
} else if (forwardedMessagesCount) {
exitForwardMode();
} else if (replyInfo && !shouldForceShowEditing) {
resetDraftReplyInfo();
}
onClear?.();
});
@ -210,15 +210,15 @@ const ComposerEmbeddedMessage: FC<OwnProps & StateProps> = ({
);
const leftIcon = useMemo(() => {
if (isShowingReply) {
return 'reply';
}
if (editingId) {
return 'edit';
}
if (isForwarding) {
return 'forward';
}
if (isShowingReply) {
return 'reply';
}
return undefined;
}, [editingId, isForwarding, isShowingReply]);
@ -398,25 +398,18 @@ export default memo(withGlobal<OwnProps>(
const senderChat = replyToPeerId ? selectChat(global, replyToPeerId) : undefined;
let message: ApiMessage | undefined;
if (replyInfo && !shouldForceShowEditing) {
message = selectChatMessage(global, replyInfo.replyToPeerId || chatId, replyInfo.replyToMsgId);
} else if (editingId) {
if (editingId) {
message = selectEditingMessage(global, chatId, threadId, messageListType);
} else if (isForwarding && forwardMessageIds!.length === 1) {
message = forwardedMessages?.[0];
} else if (replyInfo && !shouldForceShowEditing) {
message = selectChatMessage(global, replyInfo.replyToPeerId || chatId, replyInfo.replyToMsgId);
}
let sender: ApiPeer | undefined;
if (replyInfo && message && !shouldForceShowEditing) {
const { forwardInfo } = message;
const isChatWithSelf = selectIsChatWithSelf(global, chatId);
if (forwardInfo && (forwardInfo.isChannelPost || isChatWithSelf)) {
sender = selectForwardedSender(global, message);
}
if (!sender && (!forwardInfo?.hiddenUserName || Boolean(replyInfo.quoteText))) {
sender = selectSender(global, message);
}
if (editingId && message) {
sender = selectSender(global, message);
} else if (isForwarding) {
if (message) {
sender = selectForwardedSender(global, message);
@ -427,8 +420,16 @@ export default memo(withGlobal<OwnProps>(
if (!sender) {
sender = selectPeer(global, fromChatId!);
}
} else if (editingId && message) {
sender = selectSender(global, message);
} else if (replyInfo && message && !shouldForceShowEditing) {
const { forwardInfo } = message;
const isChatWithSelf = selectIsChatWithSelf(global, chatId);
if (forwardInfo && (forwardInfo.isChannelPost || isChatWithSelf)) {
sender = selectForwardedSender(global, message);
}
if (!sender && (!forwardInfo?.hiddenUserName || Boolean(replyInfo.quoteText))) {
sender = selectSender(global, message);
}
}
const forwardsHaveCaptions = forwardedMessages?.some((forward) => (

View File

@ -317,7 +317,9 @@ addActionHandler('sendMessage', (global, actions, payload): ActionReturnType =>
const chat = selectChat(global, chatId!)!;
const draft = selectDraft(global, chatId!, threadId!);
const draftReplyInfo = !isStoryReply ? draft?.replyInfo : undefined;
const isForwarding = selectTabState(global, tabId).forwardMessages?.messageIds?.length;
const draftReplyInfo = !isForwarding && !isStoryReply ? draft?.replyInfo : undefined;
const storyReplyInfo = isStoryReply ? {
type: 'story',
@ -1795,11 +1797,6 @@ addActionHandler('openChatOrTopicWithReplyInDraft', (global, actions, payload):
global = getGlobal();
if (!selectReplyCanBeSentToChat(global, toChatId, tabId)) {
actions.showNotification({ message: translate('Chat.SendNotAllowedText'), tabId });
return;
}
global = updateTabState(global, {
forwardMessages: {
...selectTabState(global, tabId).forwardMessages,
@ -1809,23 +1806,27 @@ addActionHandler('openChatOrTopicWithReplyInDraft', (global, actions, payload):
setGlobal(global);
const currentChat = selectCurrentChat(global, tabId);
if (!currentChat) return;
const currentThreadId = selectCurrentMessageList(global, tabId)?.threadId;
if (!currentChat || !currentThreadId) return;
const threadId = topicId || MAIN_THREAD_ID;
const currentChatId = currentChat.id;
const currentReplyInfo = selectDraft(global, currentChatId, threadId)?.replyInfo;
const currentReplyInfo = selectDraft(global, currentChatId, currentThreadId)?.replyInfo;
if (!currentReplyInfo) return;
if (!selectReplyCanBeSentToChat(global, toChatId, currentChatId, currentReplyInfo)) {
actions.showNotification({ message: translate('Chat.SendNotAllowedText'), tabId });
return;
}
if (!currentReplyInfo.replyToPeerId && toChatId === currentChat.id) return;
const getPeerId = () => {
if (!currentReplyInfo?.replyToPeerId) return currentChatId;
return currentReplyInfo.replyToPeerId === toChatId ? undefined : currentReplyInfo.replyToPeerId;
};
const currentThreadId = selectCurrentMessageList(global, tabId)?.threadId;
if (!currentThreadId) {
return;
}
const replyToPeerId = getPeerId();
const newReply: ApiInputMessageReplyInfo = {
...currentReplyInfo,
@ -1869,7 +1870,6 @@ addActionHandler('setForwardChatOrTopic', async (global, actions, payload): Prom
},
}, tabId);
setGlobal(global);
actions.openThread({ chatId, threadId: topicId || MAIN_THREAD_ID, tabId });
actions.closeMediaViewer({ tabId });
actions.exitMessageSelectMode({ tabId });

View File

@ -1363,15 +1363,13 @@ export function selectRequestedMessageTranslationLanguage<T extends GlobalState>
export function selectReplyCanBeSentToChat<T extends GlobalState>(
global: T,
toChatId: string,
...[tabId = getCurrentTabId()]: TabArgs<T>
fromChatId: string,
replyInfo: ApiInputMessageReplyInfo,
) {
const currentChat = selectCurrentChat(global, tabId);
if (!currentChat) return false;
const replyInfo = selectDraft(global, currentChat.id, MAIN_THREAD_ID)?.replyInfo;
if (!replyInfo || !replyInfo.replyToMsgId) return false;
const fromChatId = replyInfo?.replyToPeerId ?? currentChat.id;
if (toChatId === fromChatId) return true;
const chatMessages = selectChatMessages(global, fromChatId!);
if (!replyInfo.replyToMsgId) return false;
const fromRealChatId = replyInfo?.replyToPeerId ?? fromChatId;
if (toChatId === fromRealChatId) return true;
const chatMessages = selectChatMessages(global, fromRealChatId!);
const message = chatMessages[replyInfo.replyToMsgId];
return !isExpiredMessage(message);