Files
multica/packages/views/locales/ko/common.json
Naiyuan Qing c6783efd88 feat(views): unify avatar upload with crop editing (#5074)
* feat(views): unify avatar upload with crop editing across web/desktop

Add a shared AvatarUploadControl + AvatarCropDialog used by the user,
workspace, agent, and squad avatar entry points. Cropping (pan/zoom, fixed
1:1) and compression run client-side on canvas; the existing /api/upload-file
+ avatar_url chain is reused unchanged (no backend/API/DB changes). This
collapses four hand-rolled upload buttons into one control and removes
AvatarPicker.

Also make the shared display avatar treat all non-human actors (agent, squad,
system) as rounded squares — completing the "circles are for humans"
convention the editors already assumed, so display and editors agree.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* feat(views): rebuild avatar cropper to the "Edit avatar" reference form

Replace the hand-rolled canvas cropper with react-easy-crop to match the
requested design: full-bleed image with a dimmed overlay outside a bright
crop window, a rotate control, a zoom slider flanked by −/+, and a
Reset / Cancel / Save footer. Round window for people, rounded-square for
non-human actors; output stays a 512px square (webp, jpeg fallback) through
the same upload/avatar_url chain.

avatar-crop.ts keeps the encode pipeline and gains rotation-aware
getCroppedAvatarBlob; the interactive geometry now lives in react-easy-crop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(views): round square avatar crop frame

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-07-09 20:27:33 +08:00

64 lines
3.8 KiB
JSON

{
"avatar_upload": {
"change": "아바타 변경",
"remove": "제거",
"select_image": "이미지 파일을 선택하세요.",
"updated": "아바타를 업데이트했어요",
"failed": "아바타 업로드에 실패했어요"
},
"avatar_crop": {
"title": "아바타 편집",
"zoom": "확대/축소",
"zoom_in": "확대",
"zoom_out": "축소",
"rotate": "회전",
"reset": "초기화",
"cancel": "취소",
"apply": "저장",
"uploading": "업로드 중…",
"loading": "불러오는 중…",
"load_failed": "이미지를 불러오지 못했어요"
},
"save": "저장",
"cancel": "취소",
"delete": "삭제",
"confirm": "확인",
"loading": "로딩 중...",
"time": {
"just_now": "방금 전",
"minutes_ago": "{{count}}분 전",
"hours_ago": "{{count}}시간 전",
"days_ago": "{{count}}일 전"
},
"lark_bind": {
"page_title": "Lark 계정 연결",
"redeeming": "바인딩 토큰을 사용하는 중…",
"needs_auth_description": "바인딩을 완료하려면 Multica에 로그인하세요. 링크의 토큰이 Lark 계정을 현재 로그인된 Multica 사용자에 연결하므로, 먼저 로그인해야 합니다.",
"sign_in": "로그인",
"done_title": "연결 완료.",
"done_description": "이제 Lark에서 봇에게 보낸 메시지가 곧바로 에이전트로 전달됩니다. 이 탭은 닫아도 됩니다.",
"error_title": "바인딩을 완료하지 못했어요",
"error_admin_hint": "계속 실패한다면, 워크스페이스 관리자에게 Lark에서 바인딩 링크를 다시 보내달라고 요청하세요.",
"error_missing_token": "링크에 바인딩 토큰이 없습니다. Lark에서 봇에게 새 링크를 다시 받아주세요.",
"error_expired": "이 바인딩 링크는 유효하지 않거나 만료되었습니다(유효 시간 15분). 봇에게 새 링크를 다시 받아주세요.",
"error_already_bound": "이 Lark 계정은 이미 다른 Multica 사용자에 연결되어 있습니다. 계정 이전은 먼저 명시적으로 연결을 해제해야 합니다.",
"error_not_member": "현재 로그인한 Multica 계정이 이 워크스페이스의 멤버가 아닙니다.",
"error_unknown": "문제가 발생했어요. 다시 시도해 보고, 계속되면 워크스페이스 관리자에게 문의하세요."
},
"slack_bind": {
"page_title": "Slack 계정 연결",
"redeeming": "계정을 연결하는 중…",
"needs_auth_description": "연결을 완료하려면 Multica에 로그인하세요. 링크의 토큰이 Slack 계정을 이 Multica 사용자와 연결하므로 먼저 로그인해야 해요.",
"sign_in": "로그인",
"done_title": "연결되었어요.",
"done_description": "이제 Slack에서 봇에게 보내는 다음 메시지는 바로 에이전트로 전달돼요. 이 탭은 닫아도 됩니다.",
"error_title": "연결을 완료하지 못했어요",
"error_admin_hint": "계속 발생하면 Slack에서 봇에게 다시 메시지를 보내 새 링크를 받으세요.",
"error_missing_token": "링크에 토큰이 없어요. Slack에서 봇에게 다시 메시지를 보내 새 링크를 받으세요.",
"error_expired": "이 링크는 유효하지 않거나 만료됐어요(유효 기간 15분). 봇에게 다시 메시지를 보내 새 링크를 받으세요.",
"error_already_bound": "이 Slack 계정은 이미 다른 Multica 사용자에 연결되어 있어요. 이전하려면 먼저 명시적으로 연결을 해제해야 합니다.",
"error_not_member": "로그인한 Multica 계정이 이 워크스페이스의 멤버가 아니에요.",
"error_unknown": "문제가 발생했어요. 다시 시도해 보고, 계속되면 워크스페이스 관리자에게 문의하세요."
}
}