Message Context Menu: Fix copying message link on iOS (#1337)
This commit is contained in:
parent
45a0bca14b
commit
7728a4e703
@ -22,7 +22,7 @@ export {
|
|||||||
markMessageListRead, markMessagesRead, requestThreadInfoUpdate, searchMessagesLocal, searchMessagesGlobal,
|
markMessageListRead, markMessagesRead, requestThreadInfoUpdate, searchMessagesLocal, searchMessagesGlobal,
|
||||||
fetchWebPagePreview, editMessage, forwardMessages, loadPollOptionResults, sendPollVote, findFirstMessageIdAfterDate,
|
fetchWebPagePreview, editMessage, forwardMessages, loadPollOptionResults, sendPollVote, findFirstMessageIdAfterDate,
|
||||||
fetchPinnedMessages, fetchScheduledHistory, sendScheduledMessages, rescheduleMessage, deleteScheduledMessages,
|
fetchPinnedMessages, fetchScheduledHistory, sendScheduledMessages, rescheduleMessage, deleteScheduledMessages,
|
||||||
fetchMessageLink, reportMessages,
|
reportMessages,
|
||||||
} from './messages';
|
} from './messages';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|||||||
@ -1079,15 +1079,6 @@ export async function sendScheduledMessages({ chat, ids }: { chat: ApiChat; ids:
|
|||||||
}), true);
|
}), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchMessageLink({ chat, message }: { chat: ApiChat; message: ApiMessage }) {
|
|
||||||
return invokeRequest(new GramJs.channels.ExportMessageLink({
|
|
||||||
id: message.id,
|
|
||||||
channel: buildInputEntity(chat.id, chat.accessHash) as GramJs.InputChannel,
|
|
||||||
...(message.isInAlbum && { grouped: true }),
|
|
||||||
...(message.threadInfo && message.threadInfo.topMessageId !== message.id && { thread: true }),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateLocalDb(result: (
|
function updateLocalDb(result: (
|
||||||
GramJs.messages.MessagesSlice | GramJs.messages.Messages | GramJs.messages.ChannelMessages |
|
GramJs.messages.MessagesSlice | GramJs.messages.Messages | GramJs.messages.ChannelMessages |
|
||||||
GramJs.messages.DiscussionMessage
|
GramJs.messages.DiscussionMessage
|
||||||
|
|||||||
@ -18,9 +18,11 @@ import PinMessageModal from '../../common/PinMessageModal';
|
|||||||
import MessageContextMenu from './MessageContextMenu';
|
import MessageContextMenu from './MessageContextMenu';
|
||||||
import CalendarModal from '../../common/CalendarModal';
|
import CalendarModal from '../../common/CalendarModal';
|
||||||
import { getDayStartAt } from '../../../util/dateFormat';
|
import { getDayStartAt } from '../../../util/dateFormat';
|
||||||
|
import { copyTextToClipboard } from '../../../util/clipboard';
|
||||||
|
|
||||||
export type OwnProps = {
|
export type OwnProps = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
|
chatUsername?: string;
|
||||||
message: ApiMessage;
|
message: ApiMessage;
|
||||||
album?: IAlbum;
|
album?: IAlbum;
|
||||||
anchor: IAnchorPosition;
|
anchor: IAnchorPosition;
|
||||||
@ -49,13 +51,13 @@ type StateProps = {
|
|||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
type DispatchProps = Pick<GlobalActions, (
|
||||||
'setReplyingToId' | 'setEditingId' | 'pinMessage' | 'openForwardMenu' |
|
'setReplyingToId' | 'setEditingId' | 'pinMessage' | 'openForwardMenu' |
|
||||||
'faveSticker' | 'unfaveSticker' | 'toggleMessageSelection' | 'sendScheduledMessages' | 'rescheduleMessage' |
|
'faveSticker' | 'unfaveSticker' | 'toggleMessageSelection' | 'sendScheduledMessages' | 'rescheduleMessage'
|
||||||
'loadMessageLink'
|
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
const ContextMenuContainer: FC<OwnProps & StateProps & DispatchProps> = ({
|
const ContextMenuContainer: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||||
isOpen,
|
isOpen,
|
||||||
messageListType,
|
messageListType,
|
||||||
|
chatUsername,
|
||||||
message,
|
message,
|
||||||
album,
|
album,
|
||||||
anchor,
|
anchor,
|
||||||
@ -85,7 +87,6 @@ const ContextMenuContainer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
toggleMessageSelection,
|
toggleMessageSelection,
|
||||||
sendScheduledMessages,
|
sendScheduledMessages,
|
||||||
rescheduleMessage,
|
rescheduleMessage,
|
||||||
loadMessageLink,
|
|
||||||
}) => {
|
}) => {
|
||||||
const { transitionClassNames } = useShowTransition(isOpen, onCloseAnimationEnd, undefined, false);
|
const { transitionClassNames } = useShowTransition(isOpen, onCloseAnimationEnd, undefined, false);
|
||||||
const [isMenuOpen, setIsMenuOpen] = useState(true);
|
const [isMenuOpen, setIsMenuOpen] = useState(true);
|
||||||
@ -201,12 +202,9 @@ const ContextMenuContainer: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
}, [message.chatId, message.id, rescheduleMessage]);
|
}, [message.chatId, message.id, rescheduleMessage]);
|
||||||
|
|
||||||
const handleCopyLink = useCallback(() => {
|
const handleCopyLink = useCallback(() => {
|
||||||
loadMessageLink({
|
copyTextToClipboard(`https://t.me/${chatUsername || `c/${Math.abs(message.chatId)}`}/${message.id}`);
|
||||||
messageId: message.id,
|
|
||||||
chatId: message.chatId,
|
|
||||||
});
|
|
||||||
closeMenu();
|
closeMenu();
|
||||||
}, [closeMenu, loadMessageLink, message.chatId, message.id]);
|
}, [chatUsername, closeMenu, message.chatId, message.id]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
disableScrolling();
|
disableScrolling();
|
||||||
@ -340,6 +338,5 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
'toggleMessageSelection',
|
'toggleMessageSelection',
|
||||||
'sendScheduledMessages',
|
'sendScheduledMessages',
|
||||||
'rescheduleMessage',
|
'rescheduleMessage',
|
||||||
'loadMessageLink',
|
|
||||||
]),
|
]),
|
||||||
)(ContextMenuContainer));
|
)(ContextMenuContainer));
|
||||||
|
|||||||
@ -124,6 +124,7 @@ type OwnProps = {
|
|||||||
type StateProps = {
|
type StateProps = {
|
||||||
theme: ISettings['theme'];
|
theme: ISettings['theme'];
|
||||||
forceSenderName?: boolean;
|
forceSenderName?: boolean;
|
||||||
|
chatUsername?: string;
|
||||||
sender?: ApiUser | ApiChat;
|
sender?: ApiUser | ApiChat;
|
||||||
originSender?: ApiUser | ApiChat;
|
originSender?: ApiUser | ApiChat;
|
||||||
botSender?: ApiUser;
|
botSender?: ApiUser;
|
||||||
@ -173,6 +174,7 @@ const ANDROID_KEYBOARD_HIDE_DELAY_MS = 350;
|
|||||||
|
|
||||||
const Message: FC<OwnProps & StateProps & DispatchProps> = ({
|
const Message: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||||
message,
|
message,
|
||||||
|
chatUsername,
|
||||||
observeIntersectionForBottom,
|
observeIntersectionForBottom,
|
||||||
observeIntersectionForMedia,
|
observeIntersectionForMedia,
|
||||||
observeIntersectionForAnimatedStickers,
|
observeIntersectionForAnimatedStickers,
|
||||||
@ -869,6 +871,7 @@ const Message: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
anchor={contextMenuPosition}
|
anchor={contextMenuPosition}
|
||||||
message={message}
|
message={message}
|
||||||
album={album}
|
album={album}
|
||||||
|
chatUsername={chatUsername}
|
||||||
messageListType={messageListType}
|
messageListType={messageListType}
|
||||||
onClose={handleContextMenuClose}
|
onClose={handleContextMenuClose}
|
||||||
onCloseAnimationEnd={handleContextMenuHide}
|
onCloseAnimationEnd={handleContextMenuHide}
|
||||||
@ -915,6 +918,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const chat = selectChat(global, chatId);
|
const chat = selectChat(global, chatId);
|
||||||
const isChatWithSelf = selectIsChatWithSelf(global, chatId);
|
const isChatWithSelf = selectIsChatWithSelf(global, chatId);
|
||||||
const isChannel = chat && isChatChannel(chat);
|
const isChannel = chat && isChatChannel(chat);
|
||||||
|
const chatUsername = chat && chat.username;
|
||||||
|
|
||||||
const forceSenderName = !isChatWithSelf && isAnonymousOwnMessage(message);
|
const forceSenderName = !isChatWithSelf && isAnonymousOwnMessage(message);
|
||||||
const canShowSender = withSenderName || withAvatar || forceSenderName;
|
const canShowSender = withSenderName || withAvatar || forceSenderName;
|
||||||
@ -955,6 +959,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
theme: selectTheme(global),
|
theme: selectTheme(global),
|
||||||
|
chatUsername,
|
||||||
forceSenderName,
|
forceSenderName,
|
||||||
sender,
|
sender,
|
||||||
originSender,
|
originSender,
|
||||||
|
|||||||
@ -446,7 +446,7 @@ export type ActionTypes = (
|
|||||||
'editMessage' | 'deleteHistory' | 'enterMessageSelectMode' | 'toggleMessageSelection' | 'exitMessageSelectMode' |
|
'editMessage' | 'deleteHistory' | 'enterMessageSelectMode' | 'toggleMessageSelection' | 'exitMessageSelectMode' |
|
||||||
'openTelegramLink' | 'openChatByUsername' | 'requestThreadInfoUpdate' | 'setScrollOffset' | 'unpinAllMessages' |
|
'openTelegramLink' | 'openChatByUsername' | 'requestThreadInfoUpdate' | 'setScrollOffset' | 'unpinAllMessages' |
|
||||||
'setReplyingToId' | 'setEditingId' | 'editLastMessage' | 'saveDraft' | 'clearDraft' | 'loadPinnedMessages' |
|
'setReplyingToId' | 'setEditingId' | 'editLastMessage' | 'saveDraft' | 'clearDraft' | 'loadPinnedMessages' |
|
||||||
'loadMessageLink' | 'toggleMessageWebPage' | 'replyToNextMessage' | 'deleteChatUser' | 'deleteChat' |
|
'toggleMessageWebPage' | 'replyToNextMessage' | 'deleteChatUser' | 'deleteChat' |
|
||||||
'reportMessages' | 'focusNextReply' |
|
'reportMessages' | 'focusNextReply' |
|
||||||
// scheduled messages
|
// scheduled messages
|
||||||
'loadScheduledHistory' | 'sendScheduledMessages' | 'rescheduleMessage' | 'deleteScheduledMessages' |
|
'loadScheduledHistory' | 'sendScheduledMessages' | 'rescheduleMessage' | 'deleteScheduledMessages' |
|
||||||
|
|||||||
@ -1071,7 +1071,6 @@ channels.joinChannel#24b524c5 channel:InputChannel = Updates;
|
|||||||
channels.leaveChannel#f836aa95 channel:InputChannel = Updates;
|
channels.leaveChannel#f836aa95 channel:InputChannel = Updates;
|
||||||
channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> = Updates;
|
channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> = Updates;
|
||||||
channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
|
channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
|
||||||
channels.exportMessageLink#e63fadeb flags:# grouped:flags.0?true thread:flags.1?true channel:InputChannel id:int = ExportedMessageLink;
|
|
||||||
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
|
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
|
||||||
channels.editBanned#96e6cd81 channel:InputChannel participant:InputPeer banned_rights:ChatBannedRights = Updates;
|
channels.editBanned#96e6cd81 channel:InputChannel participant:InputPeer banned_rights:ChatBannedRights = Updates;
|
||||||
channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector<int> = Bool;
|
channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector<int> = Bool;
|
||||||
|
|||||||
@ -1071,7 +1071,6 @@ channels.joinChannel#24b524c5 channel:InputChannel = Updates;
|
|||||||
channels.leaveChannel#f836aa95 channel:InputChannel = Updates;
|
channels.leaveChannel#f836aa95 channel:InputChannel = Updates;
|
||||||
channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> = Updates;
|
channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> = Updates;
|
||||||
channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
|
channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
|
||||||
channels.exportMessageLink#e63fadeb flags:# grouped:flags.0?true thread:flags.1?true channel:InputChannel id:int = ExportedMessageLink;
|
|
||||||
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
|
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
|
||||||
channels.editBanned#96e6cd81 channel:InputChannel participant:InputPeer banned_rights:ChatBannedRights = Updates;
|
channels.editBanned#96e6cd81 channel:InputChannel participant:InputPeer banned_rights:ChatBannedRights = Updates;
|
||||||
channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector<int> = Bool;
|
channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector<int> = Bool;
|
||||||
|
|||||||
@ -52,7 +52,6 @@ import {
|
|||||||
selectNoWebPage,
|
selectNoWebPage,
|
||||||
} from '../../selectors';
|
} from '../../selectors';
|
||||||
import { rafPromise, throttle } from '../../../util/schedulers';
|
import { rafPromise, throttle } from '../../../util/schedulers';
|
||||||
import { copyTextToClipboard } from '../../../util/clipboard';
|
|
||||||
import { IS_IOS } from '../../../util/environment';
|
import { IS_IOS } from '../../../util/environment';
|
||||||
|
|
||||||
const uploadProgressCallbacks = new Map<number, ApiOnProgress>();
|
const uploadProgressCallbacks = new Map<number, ApiOnProgress>();
|
||||||
@ -858,24 +857,6 @@ addReducer('loadPinnedMessages', (global, actions, payload) => {
|
|||||||
void loadPinnedMessages(chat);
|
void loadPinnedMessages(chat);
|
||||||
});
|
});
|
||||||
|
|
||||||
addReducer('loadMessageLink', (global, actions, payload) => {
|
|
||||||
const { messageId, chatId } = payload;
|
|
||||||
const chat = selectChat(global, chatId);
|
|
||||||
const message = selectChatMessage(global, chatId, messageId);
|
|
||||||
|
|
||||||
if (!chat || !message) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
(async () => {
|
|
||||||
const result = await callApi('fetchMessageLink', { chat, message });
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
copyTextToClipboard(result.link);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
});
|
|
||||||
|
|
||||||
async function loadPinnedMessages(chat: ApiChat) {
|
async function loadPinnedMessages(chat: ApiChat) {
|
||||||
const result = await callApi('fetchPinnedMessages', { chat });
|
const result = await callApi('fetchPinnedMessages', { chat });
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user