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
|
// 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 {
|
export interface MappedMessage {
|
||||||
id: string;
|
id: string;
|
||||||
guild_id: string;
|
guild_id: string;
|
||||||
@@ -7,6 +24,8 @@ export interface MappedMessage {
|
|||||||
thread_id: string | null;
|
thread_id: string | null;
|
||||||
user_id: string;
|
user_id: string;
|
||||||
username: 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;
|
avatar_url: string | null;
|
||||||
content: string;
|
content: string;
|
||||||
edited_content: string | null;
|
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,
|
thread_id: (row.thread_id as string | null) ?? null,
|
||||||
user_id: String(row.user_id ?? ""),
|
user_id: String(row.user_id ?? ""),
|
||||||
username: String(row.username ?? ""),
|
username: String(row.username ?? ""),
|
||||||
|
server_nick: resolveServerNick(row),
|
||||||
avatar_url: (row.avatar_url as string | null) ?? null,
|
avatar_url: (row.avatar_url as string | null) ?? null,
|
||||||
content: String(row.content ?? ""),
|
content: String(row.content ?? ""),
|
||||||
edited_content: (row.edited_content as string | null) ?? null,
|
edited_content: (row.edited_content as string | null) ?? null,
|
||||||
|
|||||||
@@ -193,12 +193,21 @@ export function AnalysisView() {
|
|||||||
key={m.id}
|
key={m.id}
|
||||||
className="search-result-card hud-card flex items-start gap-3 p-3 transition-all"
|
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="min-w-0 flex-1">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="text-xs font-semibold text-ink">
|
<span className="text-xs font-semibold text-ink">
|
||||||
{m.username}
|
{m.server_nick ?? m.username}
|
||||||
</span>
|
</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">
|
<span className="font-mono text-[10px] text-ink-faint">
|
||||||
{getMessageChannelLabel(m)}
|
{getMessageChannelLabel(m)}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -564,9 +564,18 @@ function MessageDetail({
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-3 text-sm">
|
<div className="space-y-3 text-sm">
|
||||||
<div className="flex items-center gap-3">
|
<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>
|
||||||
<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">
|
<div className="mono text-[0.65rem] text-ink-faint">
|
||||||
{getMessageChannelLabel(m)} · {formatRelativeTime(m.created_at)}
|
{getMessageChannelLabel(m)} · {formatRelativeTime(m.created_at)}
|
||||||
</div>
|
</div>
|
||||||
@@ -729,12 +738,21 @@ function MessageRow({
|
|||||||
: "border-hairline bg-surface-2 hover:border-hairline-focus hover:bg-surface"
|
: "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="min-w-0 flex-1">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="truncate text-xs font-semibold text-ink">
|
<span className="truncate text-xs font-semibold text-ink">
|
||||||
{m.username}
|
{m.server_nick ?? m.username}
|
||||||
</span>
|
</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">
|
<span className="font-mono text-[10px] text-ink-muted">
|
||||||
{getMessageChannelLabel(m)}
|
{getMessageChannelLabel(m)}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -109,6 +109,8 @@ export interface MessageRecord {
|
|||||||
reference_guild_id?: string | null;
|
reference_guild_id?: string | null;
|
||||||
user_id: string;
|
user_id: string;
|
||||||
username: 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;
|
avatar_url?: string | null;
|
||||||
content: string;
|
content: string;
|
||||||
edited_content?: string | null;
|
edited_content?: string | null;
|
||||||
|
|||||||
Reference in New Issue
Block a user