Message: Generate sharing link on server (#4405)
This commit is contained in:
parent
b3e21e293a
commit
c0e82bdd0f
@ -35,7 +35,7 @@ export {
|
||||
reportMessages, sendMessageAction, fetchSeenBy, fetchSponsoredMessages, viewSponsoredMessage, fetchSendAs,
|
||||
saveDefaultSendAs, fetchUnreadReactions, readAllReactions, fetchUnreadMentions, readAllMentions, transcribeAudio,
|
||||
closePoll, fetchExtendedMedia, translateText, fetchMessageViews, fetchDiscussionMessage, clickSponsoredMessage,
|
||||
fetchOutboxReadDate,
|
||||
fetchOutboxReadDate, exportMessageLink,
|
||||
deleteSavedHistory,
|
||||
} from './messages';
|
||||
|
||||
|
||||
@ -1927,3 +1927,21 @@ export async function fetchOutboxReadDate({ chat, messageId }: { chat: ApiChat;
|
||||
|
||||
return { date: result.date };
|
||||
}
|
||||
|
||||
export async function exportMessageLink({
|
||||
id, chat, shouldIncludeThread, shouldIncludeGrouped,
|
||||
}: {
|
||||
id: number;
|
||||
chat: ApiChat;
|
||||
shouldIncludeThread?: boolean;
|
||||
shouldIncludeGrouped?: boolean;
|
||||
}) {
|
||||
const result = await invokeRequest(new GramJs.channels.ExportMessageLink({
|
||||
channel: buildInputEntity(chat.id, chat.accessHash) as GramJs.InputChannel,
|
||||
id,
|
||||
thread: shouldIncludeThread || undefined,
|
||||
grouped: shouldIncludeGrouped || undefined,
|
||||
}));
|
||||
|
||||
return result?.link;
|
||||
}
|
||||
|
||||
@ -4,11 +4,18 @@ import React, {
|
||||
} from '../../../lib/teact/teact';
|
||||
import { getActions, getGlobal, withGlobal } from '../../../global';
|
||||
|
||||
import type {
|
||||
ApiAvailableReaction, ApiChatReactions, ApiMessage, ApiReaction, ApiStickerSet, ApiStickerSetInfo, ApiThreadInfo,
|
||||
} from '../../../api/types';
|
||||
import type { MessageListType, TabState } from '../../../global/types';
|
||||
import type { IAlbum, IAnchorPosition } from '../../../types';
|
||||
import type { IAlbum, IAnchorPosition, ThreadId } from '../../../types';
|
||||
import {
|
||||
type ApiAvailableReaction,
|
||||
type ApiChatReactions,
|
||||
type ApiMessage,
|
||||
type ApiReaction,
|
||||
type ApiStickerSet,
|
||||
type ApiStickerSetInfo,
|
||||
type ApiThreadInfo,
|
||||
MAIN_THREAD_ID,
|
||||
} from '../../../api/types';
|
||||
|
||||
import { PREVIEW_AVATAR_COUNT, SERVICE_NOTIFICATIONS_USER_ID } from '../../../config';
|
||||
import {
|
||||
@ -38,7 +45,6 @@ import {
|
||||
selectIsPremiumPurchaseBlocked,
|
||||
selectIsReactionPickerOpen,
|
||||
selectMessageCustomEmojiSets,
|
||||
selectMessageLink,
|
||||
selectMessageTranslations,
|
||||
selectRequestedChatTranslationLanguage,
|
||||
selectRequestedMessageTranslationLanguage,
|
||||
@ -77,6 +83,7 @@ export type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
threadId?: ThreadId;
|
||||
availableReactions?: ApiAvailableReaction[];
|
||||
topReactions?: ApiReaction[];
|
||||
defaultTagReactions?: ApiReaction[];
|
||||
@ -120,13 +127,13 @@ type StateProps = {
|
||||
maxUniqueReactions?: number;
|
||||
canPlayAnimatedEmojis?: boolean;
|
||||
isReactionPickerOpen?: boolean;
|
||||
messageLink?: string;
|
||||
isInSavedMessages?: boolean;
|
||||
};
|
||||
|
||||
const selection = window.getSelection();
|
||||
|
||||
const ContextMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
threadId,
|
||||
availableReactions,
|
||||
topReactions,
|
||||
defaultTagReactions,
|
||||
@ -178,7 +185,6 @@ const ContextMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
canShowOriginal,
|
||||
canSelectLanguage,
|
||||
isReactionPickerOpen,
|
||||
messageLink,
|
||||
isInSavedMessages,
|
||||
onClose,
|
||||
onCloseAnimationEnd,
|
||||
@ -213,6 +219,7 @@ const ContextMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
openMessageReactionPicker,
|
||||
openPremiumModal,
|
||||
loadOutboxReadDate,
|
||||
copyMessageLink,
|
||||
} = getActions();
|
||||
|
||||
const lang = useLang();
|
||||
@ -459,7 +466,12 @@ const ContextMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const handleCopyLink = useLastCallback(() => {
|
||||
copyTextToClipboard(messageLink!);
|
||||
copyMessageLink({
|
||||
chatId: message.chatId,
|
||||
messageId: message.id,
|
||||
shouldIncludeThread: threadId !== MAIN_THREAD_ID,
|
||||
shouldIncludeGrouped: true, // TODO: Provide correct value when ability to target specific message is added
|
||||
});
|
||||
closeMenu();
|
||||
});
|
||||
|
||||
@ -728,11 +740,11 @@ export default memo(withGlobal<OwnProps>(
|
||||
: undefined;
|
||||
const canTranslate = !hasTranslation && selectCanTranslateMessage(global, message, detectedLanguage);
|
||||
const isChatTranslated = selectRequestedChatTranslationLanguage(global, message.chatId);
|
||||
const messageLink = selectMessageLink(global, message.chatId, threadId, message.id);
|
||||
|
||||
const isInSavedMessages = selectIsChatWithSelf(global, message.chatId);
|
||||
|
||||
return {
|
||||
threadId,
|
||||
availableReactions,
|
||||
topReactions,
|
||||
defaultTagReactions: defaultTags,
|
||||
@ -777,7 +789,6 @@ export default memo(withGlobal<OwnProps>(
|
||||
isMessageTranslated: hasTranslation,
|
||||
canPlayAnimatedEmojis: selectCanPlayAnimatedEmojis(global),
|
||||
isReactionPickerOpen: selectIsReactionPickerOpen(global),
|
||||
messageLink,
|
||||
isInSavedMessages,
|
||||
};
|
||||
},
|
||||
|
||||
@ -103,11 +103,7 @@ export function getMessageCopyOptions(
|
||||
options.push({
|
||||
label: 'lng_context_copy_message_link',
|
||||
icon: 'link',
|
||||
handler: () => {
|
||||
onCopyLink();
|
||||
|
||||
afterEffect?.();
|
||||
},
|
||||
handler: onCopyLink,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ import {
|
||||
SUPPORTED_IMAGE_CONTENT_TYPES,
|
||||
SUPPORTED_VIDEO_CONTENT_TYPES,
|
||||
} from '../../../config';
|
||||
import { copyTextToClipboard } from '../../../util/clipboard';
|
||||
import { isDeepLink } from '../../../util/deepLinkParser';
|
||||
import { ensureProtocol } from '../../../util/ensureProtocol';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
@ -53,6 +54,7 @@ import {
|
||||
getIsSavedDialog,
|
||||
getUserFullName,
|
||||
isChatChannel,
|
||||
isChatSuperGroup,
|
||||
isDeletedUser,
|
||||
isMessageLocal,
|
||||
isServiceNotificationMessage,
|
||||
@ -1900,6 +1902,49 @@ addActionHandler('loadOutboxReadDate', async (global, actions, payload): Promise
|
||||
}
|
||||
});
|
||||
|
||||
addActionHandler('copyMessageLink', async (global, actions, payload): Promise<void> => {
|
||||
const {
|
||||
chatId, messageId, shouldIncludeThread, shouldIncludeGrouped, tabId = getCurrentTabId(),
|
||||
} = payload;
|
||||
const chat = selectChat(global, chatId);
|
||||
if (!chat) {
|
||||
actions.showNotification({
|
||||
message: translate('ErrorOccurred'),
|
||||
tabId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isChatChannel(chat) && !isChatSuperGroup(chat)) {
|
||||
actions.showNotification({
|
||||
message: translate('lng_filters_link_private_error'),
|
||||
tabId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const link = await callApi('exportMessageLink', {
|
||||
chat,
|
||||
id: messageId,
|
||||
shouldIncludeThread,
|
||||
shouldIncludeGrouped,
|
||||
});
|
||||
|
||||
if (!link) {
|
||||
actions.showNotification({
|
||||
message: translate('ErrorOccurred'),
|
||||
tabId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
copyTextToClipboard(link);
|
||||
actions.showNotification({
|
||||
message: translate('LinkCopied'),
|
||||
tabId,
|
||||
});
|
||||
});
|
||||
|
||||
function countSortedIds(ids: number[], from: number, to: number) {
|
||||
let count = 0;
|
||||
|
||||
|
||||
@ -1414,29 +1414,21 @@ export function selectCanTranslateMessage<T extends GlobalState>(
|
||||
&& !chatRequestedLanguage;
|
||||
}
|
||||
|
||||
export function selectMessageLink<T extends GlobalState>(
|
||||
global: T, chatId: string, threadId?: ThreadId, messageId?: number,
|
||||
export function selectTopicLink<T extends GlobalState>(
|
||||
global: T, chatId: string, topicId?: ThreadId,
|
||||
) {
|
||||
const chat = selectChat(global, chatId);
|
||||
if (!chat) {
|
||||
if (!chat || !chat?.isForum) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const chatUsername = getMainUsername(chat);
|
||||
|
||||
const isChannelId = isChatChannel(chat) || isChatSuperGroup(chat);
|
||||
const normalizedId = isChannelId ? chatId.replace('-100', '') : chatId.replace('-', '');
|
||||
const normalizedId = chatId.replace('-100', '');
|
||||
|
||||
const chatPart = chatUsername || `c/${normalizedId}`;
|
||||
const threadPart = threadId && threadId !== MAIN_THREAD_ID ? `/${threadId}` : '';
|
||||
const messagePart = messageId ? `/${messageId}` : '';
|
||||
return `${TME_LINK_PREFIX}${chatPart}${threadPart}${messagePart}`;
|
||||
}
|
||||
|
||||
export function selectTopicLink<T extends GlobalState>(
|
||||
global: T, chatId: string, topicId?: ThreadId,
|
||||
) {
|
||||
return selectMessageLink(global, chatId, topicId);
|
||||
const topicPart = topicId && topicId !== MAIN_THREAD_ID ? `/${topicId}` : '';
|
||||
return `${TME_LINK_PREFIX}${chatPart}${topicPart}`;
|
||||
}
|
||||
|
||||
export function selectMessageReplyInfo<T extends GlobalState>(
|
||||
|
||||
@ -2054,6 +2054,12 @@ export interface ActionPayloads {
|
||||
markMentionsRead: {
|
||||
messageIds: number[];
|
||||
} & WithTabId;
|
||||
copyMessageLink: {
|
||||
chatId: string;
|
||||
messageId: number;
|
||||
shouldIncludeThread?: boolean;
|
||||
shouldIncludeGrouped?: boolean;
|
||||
} & WithTabId;
|
||||
|
||||
sendPollVote: {
|
||||
chatId: string;
|
||||
|
||||
@ -1455,6 +1455,7 @@ channels.joinChannel#24b524c5 channel:InputChannel = Updates;
|
||||
channels.leaveChannel#f836aa95 channel:InputChannel = Updates;
|
||||
channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> = 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.editBanned#96e6cd81 channel:InputChannel participant:InputPeer banned_rights:ChatBannedRights = Updates;
|
||||
channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector<int> = Bool;
|
||||
|
||||
@ -202,6 +202,7 @@
|
||||
"channels.leaveChannel",
|
||||
"channels.inviteToChannel",
|
||||
"channels.deleteChannel",
|
||||
"channels.exportMessageLink",
|
||||
"channels.toggleSignatures",
|
||||
"channels.editBanned",
|
||||
"channels.readMessageContents",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user