Newer
Older
navi-1 / webclient / src / utils / profileIcons.js
// Profile icons for the welcome grid.
//
// Every profile must be told apart at a glance, so the mapping is explicit for
// the profiles that ship with Navi — including the ones that used to fall
// through to a shared `ph-robot`, and including pairs whose subject is close:
// `coder` vs `developer`, and the two 3D profiles.

const PROFILE_ICONS = {
  assistant: 'ph-sparkle',
  coder: 'ph-brackets-curly',
  designer_3d: 'ph-cube',
  modeler_3d: 'ph-polygon',
  navi_code: 'ph-command',
  dispatcher: 'ph-signpost',
  secretary: 'ph-briefcase',
  developer: 'ph-code',
  discuss: 'ph-chats',
  server_admin: 'ph-terminal',
}

// Profiles can be created by an admin, so the set is open-ended. An unknown id
// gets a stable icon from this pool rather than one robot for all of them —
// stable because it is hashed from the id, so it never shifts between renders,
// and varied enough that two custom profiles rarely look alike.
const FALLBACK_ICONS = [
  'ph-robot',
  'ph-user-circle',
  'ph-atom',
  'ph-planet',
  'ph-puzzle-piece',
  'ph-lightning',
  'ph-star',
  'ph-shield',
  'ph-rocket',
  'ph-flask',
  'ph-hand-heart',
  'ph-compass',
]

function hash(value) {
  let h = 0
  for (let i = 0; i < value.length; i++) {
    h = (h * 31 + value.charCodeAt(i)) | 0
  }
  return Math.abs(h)
}

/** Icon class for a profile, as the kit's `GnAvatar`/`GnIconButton` expect it. */
export function profileIcon(profile) {
  if (!profile) return 'ph ph-robot'
  const id = profile.id ?? ''
  const cls = PROFILE_ICONS[id] ?? FALLBACK_ICONS[hash(id) % FALLBACK_ICONS.length]
  return `ph ${cls}`
}