import type { HttpContext } from '@adonisjs/core/http'; import { StatusCodes } from 'http-status-codes'; const prefixes = ['von', 'van']; export default class AvatarController { public async generateAvatar({ request, response }: HttpContext) { try { const { name, size } = request.only(['name', 'size']); const initials = this.getInitials(name); const originalColor = this.getColorFromName(name); const backgroundColor = this.lightenColor(originalColor, 60); const textColor = this.darkenColor(originalColor); const svgContent = ` ${initials} `; response.header('Content-type', 'image/svg+xml'); response.header('Cache-Control', 'no-cache'); response.header('Pragma', 'no-cache'); response.header('Expires', '0'); return response.send(svgContent); } catch (error) { return response.status(StatusCodes.OK).json({ error: error.message }); } } private getInitials(name: string) { const parts = name.split(' '); let initials = ''; if (parts.length >= 2) { const firstName = parts[0]; const lastName = parts[parts.length - 1]; const firstInitial = firstName.charAt(0).toUpperCase(); const lastInitial = lastName.charAt(0).toUpperCase(); if (prefixes.includes(lastName.toLowerCase()) && lastName === lastName.toUpperCase()) { initials = firstInitial + lastName.charAt(1).toUpperCase(); } else { initials = firstInitial + lastInitial; } } else if (parts.length === 1) { initials = parts[0].substring(0, 2).toUpperCase(); } return initials; } private getColorFromName(name: string) { let hash = 0; for (let i = 0; i < name.length; i++) { hash = name.charCodeAt(i) + ((hash << 5) - hash); } let color = '#'; for (let i = 0; i < 3; i++) { const value = (hash >> (i * 8)) & 0xff; color += ('00' + value.toString(16)).substr(-2); } return color.replace('#', ''); } private lightenColor(hexColor: string, percent: number) { let r = parseInt(hexColor.substring(0, 2), 16); let g = parseInt(hexColor.substring(2, 4), 16); let b = parseInt(hexColor.substring(4, 6), 16); r = Math.floor((r * (100 + percent)) / 100); g = Math.floor((g * (100 + percent)) / 100); b = Math.floor((b * (100 + percent)) / 100); r = r < 255 ? r : 255; g = g < 255 ? g : 255; b = b < 255 ? b : 255; const lighterHex = ((r << 16) | (g << 8) | b).toString(16); return lighterHex.padStart(6, '0'); } private darkenColor(hexColor: string) { const r = parseInt(hexColor.slice(0, 2), 16); const g = parseInt(hexColor.slice(2, 4), 16); const b = parseInt(hexColor.slice(4, 6), 16); const darkerR = Math.round(r * 0.6); const darkerG = Math.round(g * 0.6); const darkerB = Math.round(b * 0.6); const darkerColor = ((darkerR << 16) + (darkerG << 8) + darkerB).toString(16); return darkerColor.padStart(6, '0'); } }