2022-11-10 18:27:56 +04:00

120 lines
3.3 KiB
TypeScript

import type { ApiMessage } from '../../../../api/types';
import { ApiMediaFormat } from '../../../../api/types';
import * as mediaLoader from '../../../../util/mediaLoader';
import {
getMessageContact,
getMessageMediaHash,
getMessagePhoto,
getMessageText,
getMessageTextWithSpoilers,
getMessageWebPagePhoto,
getMessageWebPageVideo,
hasMessageLocalBlobUrl,
} from '../../../../global/helpers';
import {
CLIPBOARD_ITEM_SUPPORTED,
copyHtmlToClipboard,
copyImageToClipboard,
} from '../../../../util/clipboard';
import getMessageIdsForSelectedText from '../../../../util/getMessageIdsForSelectedText';
import { renderMessageText } from '../../../common/helpers/renderMessageText';
type ICopyOptions = {
label: string;
icon: string;
handler: () => void;
}[];
export function getMessageCopyOptions(
message: ApiMessage,
afterEffect?: () => void,
onCopyLink?: () => void,
onCopyMessages?: (messageIds: number[]) => void,
onCopyNumber?: () => void,
): ICopyOptions {
const options: ICopyOptions = [];
const text = getMessageText(message);
const photo = getMessagePhoto(message)
|| (!getMessageWebPageVideo(message) ? getMessageWebPagePhoto(message) : undefined);
const contact = getMessageContact(message);
const mediaHash = getMessageMediaHash(message, 'inline');
const canImageBeCopied = photo && (mediaHash || hasMessageLocalBlobUrl(message)) && CLIPBOARD_ITEM_SUPPORTED;
const selection = window.getSelection();
if (canImageBeCopied) {
options.push({
label: 'lng_context_copy_image',
icon: 'copy-media',
handler: () => {
Promise.resolve(mediaHash ? mediaLoader.fetch(mediaHash, ApiMediaFormat.BlobUrl) : photo!.blobUrl)
.then(copyImageToClipboard);
afterEffect?.();
},
});
}
if (text) {
// Detect if the user has selection in the current message
const hasSelection = Boolean((
selection?.anchorNode?.parentNode
&& (selection.anchorNode.parentNode as HTMLElement).closest('.Message .content-inner')
&& selection.toString().replace(/(?:\r\n|\r|\n)/g, '') !== ''
));
options.push({
label: getCopyLabel(hasSelection),
icon: 'copy',
handler: () => {
const messageIds = getMessageIdsForSelectedText();
if (messageIds?.length && onCopyMessages) {
onCopyMessages(messageIds);
} else if (hasSelection) {
document.execCommand('copy');
} else {
const clipboardText = renderMessageText(
message, undefined, undefined, undefined, undefined, undefined, undefined, undefined, true,
);
if (clipboardText) copyHtmlToClipboard(clipboardText.join(''), getMessageTextWithSpoilers(message)!);
}
afterEffect?.();
},
});
}
if (onCopyLink) {
options.push({
label: 'lng_context_copy_message_link',
icon: 'link',
handler: () => {
onCopyLink();
afterEffect?.();
},
});
}
if (contact && onCopyNumber) {
options.push({
label: 'lng_profile_copy_phone',
icon: 'copy',
handler: () => {
onCopyNumber();
afterEffect?.();
},
});
}
return options;
}
function getCopyLabel(hasSelection: boolean): string {
if (hasSelection) {
return 'lng_context_copy_selected';
}
return 'lng_context_copy_text';
}