- Add uploadFile method to ApiClient (FormData + 401 handling) - Add useFileUpload hook with client-side validation - ActorAvatar renders actual avatar images with fallback to initials - Account settings: replace URL input with clickable avatar upload - RichTextEditor: add Image extension, paste/drop/insertFile support - Markdown renderer: add img component for uploaded images - CommentInput & ReplyInput: add paperclip button for file attachments - Issue description: paste/drop file upload support Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
42 lines
1.2 KiB
TypeScript
42 lines
1.2 KiB
TypeScript
"use client";
|
|
|
|
import { useWorkspaceStore } from "./store";
|
|
|
|
export function useActorName() {
|
|
const members = useWorkspaceStore((s) => s.members);
|
|
const agents = useWorkspaceStore((s) => s.agents);
|
|
|
|
const getMemberName = (userId: string) => {
|
|
const m = members.find((m) => m.user_id === userId);
|
|
return m?.name ?? "Unknown";
|
|
};
|
|
|
|
const getAgentName = (agentId: string) => {
|
|
const a = agents.find((a) => a.id === agentId);
|
|
return a?.name ?? "Unknown Agent";
|
|
};
|
|
|
|
const getActorName = (type: string, id: string) => {
|
|
if (type === "member") return getMemberName(id);
|
|
if (type === "agent") return getAgentName(id);
|
|
return "System";
|
|
};
|
|
|
|
const getActorInitials = (type: string, id: string) => {
|
|
const name = getActorName(type, id);
|
|
return name
|
|
.split(" ")
|
|
.map((w) => w[0])
|
|
.join("")
|
|
.toUpperCase()
|
|
.slice(0, 2);
|
|
};
|
|
|
|
const getActorAvatarUrl = (type: string, id: string): string | null => {
|
|
if (type === "member") return members.find((m) => m.user_id === id)?.avatar_url ?? null;
|
|
if (type === "agent") return agents.find((a) => a.id === id)?.avatar_url ?? null;
|
|
return null;
|
|
};
|
|
|
|
return { getMemberName, getAgentName, getActorName, getActorInitials, getActorAvatarUrl };
|
|
}
|