Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 49 additions & 8 deletions desktop/src/features/messages/ui/MessageActionBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,32 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "@/shared/ui/tooltip";
const ACTION_BUTTON_CLASS = "h-8 w-8 rounded-full p-0";
const ACTION_ICON_CLASS = "!h-4 !w-4";

/** Copying a message link is offered from both the hover action bar and the
* More menu; both paths share this exact link-building + toast behavior. */
function copyMessageLink(channelId: string, message: TimelineMessage) {
const { rootId } = getThreadReference(message.tags ?? []);
const link = buildMessageLink({
channelId,
messageId: message.id,
threadRootId: rootId,
});
copyTextToClipboard(link, "Link copied to clipboard");
}

/** Gate shared by every copy-link surface: pending sends have no delivered
* event to link to, huddle system rows aren't linkable, and callers without
* a channelId (e.g. inbox preview rows) can't build the link. */
function canCopyMessageLink(
message: TimelineMessage,
channelId: string | null | undefined,
): channelId is string {
return (
!message.pending &&
message.kind !== KIND_HUDDLE_STARTED &&
Boolean(channelId)
);
}

function MoreActionsMenu({
channelId,
message,
Expand Down Expand Up @@ -242,17 +268,11 @@ function MoreActionsMenu({
</DropdownMenuItem>
) : null}

{hasCopyActions && channelId ? (
{canCopyMessageLink(message, channelId) ? (
<DropdownMenuItem
data-testid={`copy-message-link-${message.id}`}
onClick={() => {
const { rootId } = getThreadReference(message.tags ?? []);
const link = buildMessageLink({
channelId,
messageId: message.id,
threadRootId: rootId,
});
copyTextToClipboard(link, "Link copied to clipboard");
copyMessageLink(channelId, message);
}}
>
<Link2 className="h-4 w-4" />
Expand Down Expand Up @@ -566,6 +586,27 @@ export const MessageActionBar = React.memo(function MessageActionBar({
</Tooltip>
) : null}

{canCopyMessageLink(message, channelId) ? (
<Tooltip>
<TooltipTrigger asChild>
<Button
aria-label="Copy link"
className={ACTION_BUTTON_CLASS}
data-testid={`copy-link-message-${message.id}`}
onClick={() => {
copyMessageLink(channelId, message);
}}
size="sm"
type="button"
variant="ghost"
>
<Link2 className={ACTION_ICON_CLASS} />
</Button>
</TooltipTrigger>
<TooltipContent>Copy link</TooltipContent>
</Tooltip>
) : null}

{hasMoreMenuActions ? (
<MoreActionsMenu
channelId={channelId}
Expand Down
Loading