feat: 계정정보 프로필 사진 — 구글 아바타 우선 + 변경/되돌리기
- 아바타 표시 우선순위: 사용자 지정(profileImage) > 구글(googlePicture) > 이니셜 - 사진 변경: 이미지 선택 → 정사각형 크롭·192px 축소(JPEG) → PUT /auth/profile-image - 되돌리기: 사용자 지정 사진 해제 → 구글 사진(없으면 이니셜)으로 폴백 - authApi.updateProfileImage 추가, utils/avatar.js(표시 소스/이니셜/다운스케일) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
// 프로필 아바타 유틸 — 표시 우선순위(커스텀 > 구글 > 이니셜)와 업로드용 다운스케일.
|
||||
|
||||
/**
|
||||
* 표시할 아바타 이미지 소스를 고른다.
|
||||
* 우선순위: 사용자 지정(profileImage) > 구글 아바타(googlePicture) > null(이니셜 폴백)
|
||||
*/
|
||||
export function avatarSrc(user) {
|
||||
if (!user) return null
|
||||
return user.profileImage || user.googlePicture || null
|
||||
}
|
||||
|
||||
/** 이름/아이디에서 이니셜(첫 글자) 한 글자 — 이미지 없을 때 폴백 */
|
||||
export function avatarInitial(user) {
|
||||
const s = (user?.name || user?.loginId || '').trim()
|
||||
return s ? s[0].toUpperCase() : '?'
|
||||
}
|
||||
|
||||
/**
|
||||
* 업로드용으로 이미지 파일을 정사각형으로 크롭·축소해 JPEG data URL 로 변환한다.
|
||||
* (서버/로컬 저장 용량을 작게 — 기본 192px)
|
||||
*/
|
||||
export function fileToAvatarDataUrl(file, size = 192, quality = 0.85) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!file || !file.type?.startsWith('image/')) {
|
||||
reject(new Error('이미지 파일이 아닙니다.'))
|
||||
return
|
||||
}
|
||||
const url = URL.createObjectURL(file)
|
||||
const img = new Image()
|
||||
img.onload = () => {
|
||||
try {
|
||||
const canvas = document.createElement('canvas')
|
||||
canvas.width = size
|
||||
canvas.height = size
|
||||
const ctx = canvas.getContext('2d')
|
||||
// 중앙 정사각형 크롭(cover)
|
||||
const min = Math.min(img.width, img.height)
|
||||
const sx = (img.width - min) / 2
|
||||
const sy = (img.height - min) / 2
|
||||
ctx.drawImage(img, sx, sy, min, min, 0, 0, size, size)
|
||||
const dataUrl = canvas.toDataURL('image/jpeg', quality)
|
||||
URL.revokeObjectURL(url)
|
||||
resolve(dataUrl)
|
||||
} catch (e) {
|
||||
URL.revokeObjectURL(url)
|
||||
reject(e)
|
||||
}
|
||||
}
|
||||
img.onerror = () => {
|
||||
URL.revokeObjectURL(url)
|
||||
reject(new Error('이미지를 읽지 못했습니다.'))
|
||||
}
|
||||
img.src = url
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user