import { Injectable, inject } from '@angular/core'; import { ElectronBridgeService } from '../../../../core/platform/electron/electron-bridge.service'; import { User } from '../../../../shared-kernel'; import { ProcessedProfileAvatar, resolveProfileAvatarStorageFileName } from '../../domain/profile-avatar.models'; const LEGACY_PROFILE_FILE_NAMES = [ 'profile.webp', 'profile.gif', 'profile.jpg', 'profile.jpeg', 'profile.png' ]; @Injectable({ providedIn: 'root' }) export class ProfileAvatarStorageService { private readonly electronBridge = inject(ElectronBridgeService); async persistProcessedAvatar( user: Pick, avatar: Pick ): Promise { const electronApi = this.electronBridge.getApi(); if (!electronApi) { return; } const appDataPath = await electronApi.getAppDataPath(); const usernameSegment = this.sanitizePathSegment(user.username || user.displayName || user.id || 'user'); const directoryPath = `${appDataPath}/user/${usernameSegment}/profile`; const targetFileName = resolveProfileAvatarStorageFileName(avatar.avatarMime); await electronApi.ensureDir(directoryPath); for (const fileName of LEGACY_PROFILE_FILE_NAMES) { const filePath = `${directoryPath}/${fileName}`; if (fileName !== targetFileName && await electronApi.fileExists(filePath)) { await electronApi.deleteFile(filePath); } } await electronApi.writeFile(`${directoryPath}/${targetFileName}`, avatar.base64); } private sanitizePathSegment(value: string): string { const normalized = value .trim() .replace(/[^a-zA-Z0-9._-]+/g, '-') .replace(/^-+|-+$/g, '') .slice(0, 80); return normalized || 'user'; } }