mirror of
https://github.com/block/buzz.git
synced 2026-11-12 12:22:06 +00:00
Refine conversation visual affordances (#615)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -33,3 +33,28 @@ export function resolveMentionNames(
|
||||
|
||||
return names.size > 0 ? [...names] : undefined;
|
||||
}
|
||||
|
||||
export function resolveMentionPubkeysByName(
|
||||
tags: string[][] | undefined,
|
||||
profiles: Record<string, UserProfileSummary> | undefined,
|
||||
): Record<string, string> | undefined {
|
||||
if (!profiles || !tags) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const pubkeysByName: Record<string, string> = {};
|
||||
|
||||
for (const tag of tags) {
|
||||
if (tag[0] !== "p" || !tag[1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const pubkey = tag[1].toLowerCase();
|
||||
const displayName = profiles[pubkey]?.displayName?.trim();
|
||||
if (displayName) {
|
||||
pubkeysByName[displayName.toLowerCase()] = pubkey;
|
||||
}
|
||||
}
|
||||
|
||||
return Object.keys(pubkeysByName).length > 0 ? pubkeysByName : undefined;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import remarkGfm from "remark-gfm";
|
||||
import { toast } from "sonner";
|
||||
|
||||
import { useAppNavigation } from "@/app/navigation/useAppNavigation";
|
||||
import { UserProfilePopover } from "@/features/profile/ui/UserProfilePopover";
|
||||
import { invokeTauri } from "@/shared/api/tauri";
|
||||
import type { Channel } from "@/shared/api/types";
|
||||
import { useChannelNavigation } from "@/shared/context/ChannelNavigationContext";
|
||||
@@ -34,6 +35,7 @@ type MarkdownProps = {
|
||||
content: string;
|
||||
imetaByUrl?: ImetaLookup;
|
||||
mentionNames?: string[];
|
||||
mentionPubkeysByName?: Record<string, string>;
|
||||
searchQuery?: string;
|
||||
tight?: boolean;
|
||||
};
|
||||
@@ -106,6 +108,7 @@ function createMarkdownComponents(
|
||||
channels: Channel[],
|
||||
onOpenChannel: (channelId: string) => void,
|
||||
imetaByUrl?: ImetaLookup,
|
||||
mentionPubkeysByName?: Record<string, string>,
|
||||
): Components {
|
||||
const paragraphClassName =
|
||||
variant === "tight"
|
||||
@@ -322,14 +325,27 @@ function createMarkdownComponents(
|
||||
ul: ({ children }) => (
|
||||
<ul className={cn("list-disc", listClassName)}>{children}</ul>
|
||||
),
|
||||
mention: ({ children }: { children?: React.ReactNode }) => (
|
||||
<span
|
||||
data-mention=""
|
||||
className="rounded-md bg-primary/15 px-1 py-0.5 text-sm font-semibold text-primary"
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
),
|
||||
mention: ({ children }: { children?: React.ReactNode }) => {
|
||||
const mentionText = String(children ?? "");
|
||||
const mentionName = mentionText.replace(/^@/, "").trim().toLowerCase();
|
||||
const pubkey = mentionPubkeysByName?.[mentionName];
|
||||
const mentionNode = (
|
||||
<span
|
||||
data-mention=""
|
||||
className="cursor-pointer rounded-md bg-primary/15 px-1 py-0.5 text-sm font-semibold text-primary transition-colors hover:bg-primary/25 hover:text-primary/90"
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
|
||||
return pubkey ? (
|
||||
<UserProfilePopover pubkey={pubkey} triggerElement="span">
|
||||
{mentionNode}
|
||||
</UserProfilePopover>
|
||||
) : (
|
||||
mentionNode
|
||||
);
|
||||
},
|
||||
"channel-link": ({ children }: { children?: React.ReactNode }) => {
|
||||
const text = String(children ?? "");
|
||||
const channelName = text.startsWith("#") ? text.slice(1) : text;
|
||||
@@ -374,6 +390,7 @@ function MarkdownInner({
|
||||
content,
|
||||
imetaByUrl,
|
||||
mentionNames,
|
||||
mentionPubkeysByName,
|
||||
searchQuery,
|
||||
tight = false,
|
||||
}: MarkdownProps) {
|
||||
@@ -394,8 +411,9 @@ function MarkdownInner({
|
||||
void goChannel(channelId);
|
||||
},
|
||||
imetaByUrl,
|
||||
mentionPubkeysByName,
|
||||
),
|
||||
[goChannel, variant, channels, imetaByUrl],
|
||||
[goChannel, variant, channels, imetaByUrl, mentionPubkeysByName],
|
||||
);
|
||||
|
||||
// biome-ignore lint/suspicious/noExplicitAny: PluggableList type not directly importable
|
||||
@@ -462,6 +480,7 @@ export const Markdown = React.memo(
|
||||
prev.className === next.className &&
|
||||
prev.compact === next.compact &&
|
||||
prev.tight === next.tight &&
|
||||
prev.mentionPubkeysByName === next.mentionPubkeysByName &&
|
||||
shallowArrayEqual(prev.mentionNames, next.mentionNames) &&
|
||||
shallowArrayEqual(prev.channelNames, next.channelNames) &&
|
||||
prev.imetaByUrl === next.imetaByUrl &&
|
||||
|
||||
Reference in New Issue
Block a user