fix: render server nick per user in messages tab and analysis
Extract server_nick from metadata.member.displayName in backend messageMapper, add server_nick to frontend MessageRecord type, and update messages view + analysis view to display the member's server-specific nickname (with @username as secondary context) instead of the global username.
This commit is contained in:
@@ -1,5 +1,22 @@
|
||||
// Shared message row mapper for backend repository modules
|
||||
|
||||
function resolveServerNick(row: Record<string, unknown>): string | null {
|
||||
const metadata = row.metadata;
|
||||
if (!metadata || typeof metadata !== "string") {
|
||||
return (row.username as string | null) ?? null;
|
||||
}
|
||||
try {
|
||||
const parsed = JSON.parse(metadata) as {
|
||||
member?: { displayName?: string | null } | null;
|
||||
};
|
||||
return (
|
||||
parsed?.member?.displayName ?? (row.username as string | null) ?? null
|
||||
);
|
||||
} catch {
|
||||
return (row.username as string | null) ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
export interface MappedMessage {
|
||||
id: string;
|
||||
guild_id: string;
|
||||
@@ -7,6 +24,8 @@ export interface MappedMessage {
|
||||
thread_id: string | null;
|
||||
user_id: string;
|
||||
username: string;
|
||||
/** Member's server-specific display name (nickname), from metadata.member.displayName. Falls back to username when absent. */
|
||||
server_nick: string | null;
|
||||
avatar_url: string | null;
|
||||
content: string;
|
||||
edited_content: string | null;
|
||||
@@ -42,6 +61,7 @@ export function mapMessageRow(row: Record<string, unknown>): MappedMessage {
|
||||
thread_id: (row.thread_id as string | null) ?? null,
|
||||
user_id: String(row.user_id ?? ""),
|
||||
username: String(row.username ?? ""),
|
||||
server_nick: resolveServerNick(row),
|
||||
avatar_url: (row.avatar_url as string | null) ?? null,
|
||||
content: String(row.content ?? ""),
|
||||
edited_content: (row.edited_content as string | null) ?? null,
|
||||
|
||||
@@ -193,12 +193,21 @@ export function AnalysisView() {
|
||||
key={m.id}
|
||||
className="search-result-card hud-card flex items-start gap-3 p-3 transition-all"
|
||||
>
|
||||
<Avatar src={m.avatar_url} name={m.username} size={32} />
|
||||
<Avatar
|
||||
src={m.avatar_url}
|
||||
name={m.server_nick ?? m.username}
|
||||
size={32}
|
||||
/>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-xs font-semibold text-ink">
|
||||
{m.username}
|
||||
{m.server_nick ?? m.username}
|
||||
</span>
|
||||
{m.server_nick && m.server_nick !== m.username && (
|
||||
<span className="font-mono text-[10px] text-ink-muted">
|
||||
@{m.username}
|
||||
</span>
|
||||
)}
|
||||
<span className="font-mono text-[10px] text-ink-faint">
|
||||
{getMessageChannelLabel(m)}
|
||||
</span>
|
||||
|
||||
@@ -564,9 +564,18 @@ function MessageDetail({
|
||||
return (
|
||||
<div className="space-y-3 text-sm">
|
||||
<div className="flex items-center gap-3">
|
||||
<Avatar src={m.avatar_url} name={m.username} size={40} />
|
||||
<Avatar
|
||||
src={m.avatar_url}
|
||||
name={m.server_nick ?? m.username}
|
||||
size={40}
|
||||
/>
|
||||
<div>
|
||||
<div className="font-semibold text-ink">{m.username}</div>
|
||||
<div className="font-semibold text-ink">
|
||||
{m.server_nick ?? m.username}
|
||||
</div>
|
||||
{m.server_nick && m.server_nick !== m.username && (
|
||||
<div className="text-[11px] text-ink-muted">@{m.username}</div>
|
||||
)}
|
||||
<div className="mono text-[0.65rem] text-ink-faint">
|
||||
{getMessageChannelLabel(m)} · {formatRelativeTime(m.created_at)}
|
||||
</div>
|
||||
@@ -729,12 +738,21 @@ function MessageRow({
|
||||
: "border-hairline bg-surface-2 hover:border-hairline-focus hover:bg-surface"
|
||||
}`}
|
||||
>
|
||||
<Avatar src={m.avatar_url} name={m.username} size={32} />
|
||||
<Avatar
|
||||
src={m.avatar_url}
|
||||
name={m.server_nick ?? m.username}
|
||||
size={32}
|
||||
/>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="truncate text-xs font-semibold text-ink">
|
||||
{m.username}
|
||||
{m.server_nick ?? m.username}
|
||||
</span>
|
||||
{m.server_nick && m.server_nick !== m.username && (
|
||||
<span className="truncate font-mono text-[10px] text-ink-muted">
|
||||
@{m.username}
|
||||
</span>
|
||||
)}
|
||||
<span className="font-mono text-[10px] text-ink-muted">
|
||||
{getMessageChannelLabel(m)}
|
||||
</span>
|
||||
|
||||
@@ -109,6 +109,8 @@ export interface MessageRecord {
|
||||
reference_guild_id?: string | null;
|
||||
user_id: string;
|
||||
username: string;
|
||||
/** Member's server-specific display name (nickname), from metadata.member.displayName. Falls back to username. */
|
||||
server_nick?: string | null;
|
||||
avatar_url?: string | null;
|
||||
content: string;
|
||||
edited_content?: string | null;
|
||||
|
||||
Reference in New Issue
Block a user