diff --git a/web/utils/tooltip-utils.js b/web/utils/tooltip-utils.js
--- a/web/utils/tooltip-utils.js
+++ b/web/utils/tooltip-utils.js
@@ -9,7 +9,7 @@
threadHasPermission,
useSidebarExistsOrCanBeCreated,
} from 'lib/shared/thread-utils';
-import { isComposableMessageType } from 'lib/types/message-types';
+import { isComposableMessageType, messageTypes } from 'lib/types/message-types';
import type { ThreadInfo } from 'lib/types/thread-types';
import { threadPermissions } from 'lib/types/thread-types';
import { longAbsoluteDate } from 'lib/utils/date-utils';
@@ -29,6 +29,7 @@
useOnClickPendingSidebar,
useOnClickThread,
} from '../selectors/thread-selectors';
+import SWMansionIcon from '../SWMansionIcon.react';
import { calculateMaxTextWidth } from '../utils/text-utils';
export const tooltipPositions = Object.freeze({
@@ -410,16 +411,37 @@
}, [addReply, item.messageInfo.type, messageInfo, threadInfo]);
}
+function useMessageCopyAction(
+ item: ChatMessageInfoItem,
+): ?MessageTooltipAction {
+ const { messageInfo } = item;
+ return React.useMemo(() => {
+ if (messageInfo.type !== messageTypes.TEXT) {
+ return null;
+ }
+ const buttonContent = ;
+ const onClick = async () => {
+ await navigator.clipboard.writeText(messageInfo.text);
+ };
+ return {
+ actionButtonContent: buttonContent,
+ onClick,
+ label: 'Copy',
+ };
+ }, [messageInfo]);
+}
+
function useMessageTooltipActions(
item: ChatMessageInfoItem,
threadInfo: ThreadInfo,
): $ReadOnlyArray {
const sidebarAction = useMessageTooltipSidebarAction(item, threadInfo);
const replyAction = useMessageTooltipReplyAction(item, threadInfo);
- return React.useMemo(() => [replyAction, sidebarAction].filter(Boolean), [
- replyAction,
- sidebarAction,
- ]);
+ const copyAction = useMessageCopyAction(item);
+ return React.useMemo(
+ () => [replyAction, sidebarAction, copyAction].filter(Boolean),
+ [replyAction, sidebarAction, copyAction],
+ );
}
type UseMessageTooltipArgs = {