116 lines
3.9 KiB
TypeScript
116 lines
3.9 KiB
TypeScript
import type {
|
|
AvatarGenerationPort,
|
|
AvatarGenerationOptions,
|
|
AvatarGenerationResult
|
|
} from '@gridpilot/media';
|
|
|
|
/**
|
|
* Demo implementation of AvatarGenerationPort.
|
|
*
|
|
* In production, this would use a real AI image generation API like:
|
|
* - OpenAI DALL-E
|
|
* - Midjourney API
|
|
* - Stable Diffusion
|
|
* - RunwayML
|
|
*
|
|
* For demo purposes, this returns placeholder avatar images.
|
|
*/
|
|
export class DemoAvatarGenerationAdapter implements AvatarGenerationPort {
|
|
private readonly placeholderAvatars: Record<string, string[]> = {
|
|
red: [
|
|
'/images/avatars/generated/red-1.png',
|
|
'/images/avatars/generated/red-2.png',
|
|
'/images/avatars/generated/red-3.png',
|
|
],
|
|
blue: [
|
|
'/images/avatars/generated/blue-1.png',
|
|
'/images/avatars/generated/blue-2.png',
|
|
'/images/avatars/generated/blue-3.png',
|
|
],
|
|
green: [
|
|
'/images/avatars/generated/green-1.png',
|
|
'/images/avatars/generated/green-2.png',
|
|
'/images/avatars/generated/green-3.png',
|
|
],
|
|
yellow: [
|
|
'/images/avatars/generated/yellow-1.png',
|
|
'/images/avatars/generated/yellow-2.png',
|
|
'/images/avatars/generated/yellow-3.png',
|
|
],
|
|
orange: [
|
|
'/images/avatars/generated/orange-1.png',
|
|
'/images/avatars/generated/orange-2.png',
|
|
'/images/avatars/generated/orange-3.png',
|
|
],
|
|
purple: [
|
|
'/images/avatars/generated/purple-1.png',
|
|
'/images/avatars/generated/purple-2.png',
|
|
'/images/avatars/generated/purple-3.png',
|
|
],
|
|
black: [
|
|
'/images/avatars/generated/black-1.png',
|
|
'/images/avatars/generated/black-2.png',
|
|
'/images/avatars/generated/black-3.png',
|
|
],
|
|
white: [
|
|
'/images/avatars/generated/white-1.png',
|
|
'/images/avatars/generated/white-2.png',
|
|
'/images/avatars/generated/white-3.png',
|
|
],
|
|
pink: [
|
|
'/images/avatars/generated/pink-1.png',
|
|
'/images/avatars/generated/pink-2.png',
|
|
'/images/avatars/generated/pink-3.png',
|
|
],
|
|
cyan: [
|
|
'/images/avatars/generated/cyan-1.png',
|
|
'/images/avatars/generated/cyan-2.png',
|
|
'/images/avatars/generated/cyan-3.png',
|
|
],
|
|
};
|
|
|
|
async generateAvatars(options: AvatarGenerationOptions): Promise<AvatarGenerationResult> {
|
|
// Simulate AI processing time (1-3 seconds)
|
|
await this.delay(1500 + Math.random() * 1500);
|
|
|
|
// Log what would be sent to the AI (for debugging)
|
|
console.log('[DemoAvatarGeneration] Would generate with prompt:', options.prompt);
|
|
console.log('[DemoAvatarGeneration] Suit color:', options.suitColor);
|
|
console.log('[DemoAvatarGeneration] Style:', options.style);
|
|
console.log('[DemoAvatarGeneration] Count:', options.count);
|
|
|
|
// For demo, return placeholder URLs based on suit color
|
|
// In production, these would be actual AI-generated images
|
|
const colorAvatars = this.placeholderAvatars[options.suitColor] || this.placeholderAvatars.blue;
|
|
|
|
// Generate unique URLs with a hash to simulate different generations
|
|
const hash = this.generateHash(options.facePhotoUrl + Date.now());
|
|
const avatars = colorAvatars.slice(0, options.count).map((baseUrl, index) => {
|
|
// In demo mode, use dicebear or similar for generating varied avatars
|
|
const seed = `${hash}-${options.suitColor}-${index}`;
|
|
return {
|
|
url: `https://api.dicebear.com/7.x/personas/svg?seed=${seed}&backgroundColor=transparent`,
|
|
thumbnailUrl: `https://api.dicebear.com/7.x/personas/svg?seed=${seed}&backgroundColor=transparent&size=64`,
|
|
};
|
|
});
|
|
|
|
return {
|
|
success: true,
|
|
avatars,
|
|
};
|
|
}
|
|
|
|
private delay(ms: number): Promise<void> {
|
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
}
|
|
|
|
private generateHash(input: string): string {
|
|
let hash = 0;
|
|
for (let i = 0; i < input.length; i++) {
|
|
const char = input.charCodeAt(i);
|
|
hash = ((hash << 5) - hash) + char;
|
|
hash = hash & hash;
|
|
}
|
|
return Math.abs(hash).toString(36);
|
|
}
|
|
} |