Spaces:
Sleeping
Sleeping
| import { useCollaborationStore } from '../../store/collaborationStore'; | |
| const AVATAR_COLORS = [ | |
| '#22d3ee', '#f472b6', '#34d399', '#fbbf24', '#a78bfa', | |
| '#fb923c', '#4ade80', '#f87171', '#38bdf8', '#c084fc', | |
| ]; | |
| function getColor(userId: string): string { | |
| let hash = 0; | |
| for (let i = 0; i < userId.length; i++) { | |
| hash = ((hash << 5) - hash) + userId.charCodeAt(i); | |
| } | |
| return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length]; | |
| } | |
| export default function CollaboratorAvatars({ fileId }: { fileId?: string }) { | |
| const collaborators = useCollaborationStore((s) => s.collaborators); | |
| const connected = useCollaborationStore((s) => s.connected); | |
| if (!connected || collaborators.length === 0) return null; | |
| const visible = fileId | |
| ? collaborators.filter((c) => c.activeFileId === fileId) | |
| : collaborators; | |
| if (visible.length === 0) return null; | |
| return ( | |
| <div className="flex items-center -space-x-1.5"> | |
| {visible.map((c) => ( | |
| <div | |
| key={c.userId} | |
| className="relative group" | |
| > | |
| <div | |
| className="w-6 h-6 rounded-full flex items-center justify-center text-[10px] font-bold text-white ring-2 ring-surface-900 cursor-help" | |
| style={{ backgroundColor: getColor(c.userId) }} | |
| > | |
| {c.username.charAt(0).toUpperCase()} | |
| </div> | |
| <div className="absolute bottom-full left-1/2 -translate-x-1/2 mb-1 hidden group-hover:block z-50"> | |
| <div className="bg-surface-800 border border-surface-700 rounded px-2 py-1 text-xs text-white whitespace-nowrap shadow-lg"> | |
| <div className="font-medium">{c.username}</div> | |
| <div className="text-surface-400">{c.permission}</div> | |
| </div> | |
| </div> | |
| </div> | |
| ))} | |
| </div> | |
| ); | |
| } | |
| export { getColor }; | |