From 173f547d8b7a5e12d93a3f1a4645044cb2f51e68 Mon Sep 17 00:00:00 2001 From: zenn Date: Tue, 7 Apr 2026 13:31:00 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8B=B5=EA=B8=80=20=EC=9E=85=EB=A0=A5=20UX=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/history.md | 3 ++ docs/todo.md | 1 + docs/update.md | 5 ++ .../src/components/TierListCommentsCard.vue | 52 +++++++++++++++++-- 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/docs/history.md b/docs/history.md index 3b4a7a5..ede45eb 100644 --- a/docs/history.md +++ b/docs/history.md @@ -1,5 +1,8 @@ # 의사결정 이력 +## 2026-04-07 v1.1.3 +- 댓글 답글 입력창은 포커스 상태에만 의존하지 않고, 비포커스 상태에서도 시각적 경계를 명확히 주기로 했다. 댓글 UI는 에디터 안의 부가 기능이지만 사용자가 바로 이해할 수 있어야 하므로 카드형 배경과 기본 테두리를 유지한다. + ## 2026-04-07 v1.1.2 - 댓글/알림 기능처럼 새 테이블을 뒤늦게 붙이는 경우 `CREATE TABLE IF NOT EXISTS`만으로는 충분하지 않다고 판단했다. 이미 남아 있는 예전 스키마와 충돌할 수 있으므로, 서버 시작 시 `ALTER TABLE ... ADD COLUMN IF NOT EXISTS` 형태의 점진 마이그레이션을 함께 넣는 방향으로 유지한다. diff --git a/docs/todo.md b/docs/todo.md index 7078fba..a40895a 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -1,6 +1,7 @@ # 할 일 및 이슈 ## 단기 확인 +- `v1.1.3` 이후 답글 작성 시 입력창이 열리자마자 포커스를 받고, 포커스 전에도 카드/입력 경계가 분명하게 보이는지 다크/라이트 모드 모두에서 확인한다. - `v1.1.2` 반영 후 실제 운영/로컬 DB에서 서버를 다시 띄워 `comment_notifications.is_read` 컬럼이 자동 보강되는지, `댓글 관리` 메뉴 unread dot과 `/api/comments/inbox/unread-count`가 더 이상 SQL 오류 없이 동작하는지 확인한다. - `v1.1.1` 댓글 복구 이후 다음 흐름을 우선 QA한다: 공개 티어표 프리뷰 하단 댓글 노출, 댓글 작성/답글 작성/본인 댓글 삭제, 댓글 관리 메뉴 red dot, 댓글 관리 화면에서 `안 읽은 댓글만 보기`와 `모두 읽음 처리`, 카드 클릭 후 해당 댓글 위치 스크롤. - 작성자 본인 티어표 편집 화면과 타인 티어표 프리뷰 화면에서 같은 댓글 카드가 모두 자연스럽게 보이는지, 새로고침 후에도 기존 에디터 회귀 없이 댓글 카드만 안정적으로 붙는지 확인한다. diff --git a/docs/update.md b/docs/update.md index c382ec2..9dfa195 100644 --- a/docs/update.md +++ b/docs/update.md @@ -1,5 +1,10 @@ # 업데이트 로그 +## 2026-04-07 v1.1.3 +- 댓글 답글 입력 UX를 다듬었다. `답글` 버튼을 누르면 입력창이 열리자마자 자동으로 포커스가 이동하고, 포커스 전에도 구분이 되도록 답글 입력 영역 카드와 textarea 기본 경계선을 보강했다. +- 답글 등록 버튼도 기존의 작은 기본형 버튼 대신 프로젝트 전반의 저장 계열 CTA 문법과 같은 `btn--save` 스타일로 맞췄다. +- 확인: `npm run build` + ## 2026-04-07 v1.1.2 - 댓글 알림 테이블을 기존 DB에서도 안전하게 올릴 수 있도록 스키마 보정 로직을 추가했다. 예전 형태의 `comment_notifications` 또는 `tierlist_comments` 테이블이 이미 있어도 `ALTER TABLE ... ADD COLUMN IF NOT EXISTS`로 `is_read`, `read_at`, `notification_type`, `actor_user_id`, `parent_comment_id`, `updated_at`를 보강한다. - 이 수정으로 기존 DB에서 `/api/comments/inbox/unread-count` 호출 시 `Unknown column 'is_read' in 'WHERE'`가 나던 문제를 해결한다. diff --git a/frontend/src/components/TierListCommentsCard.vue b/frontend/src/components/TierListCommentsCard.vue index d333a08..d75f17d 100644 --- a/frontend/src/components/TierListCommentsCard.vue +++ b/frontend/src/components/TierListCommentsCard.vue @@ -38,6 +38,7 @@ const replyDrafts = ref({}) const openedReplyComposerId = ref('') const submittingTargetId = ref('') const deletingCommentId = ref('') +const replyInputRefs = ref({}) let activeCommentRetryTimer = 0 const totalCommentCount = computed(() => @@ -169,8 +170,33 @@ async function deleteComment(commentId) { } } -function toggleReplyComposer(commentId) { - openedReplyComposerId.value = openedReplyComposerId.value === commentId ? '' : commentId +function registerReplyInput(commentId, element) { + if (!commentId) return + if (element) { + replyInputRefs.value[commentId] = element + return + } + delete replyInputRefs.value[commentId] +} + +async function focusReplyInput(commentId) { + if (!commentId) return + await nextTick() + const target = replyInputRefs.value[commentId] + if (target && typeof target.focus === 'function') { + target.focus() + const value = target.value || '' + if (typeof target.setSelectionRange === 'function') { + target.setSelectionRange(value.length, value.length) + } + } +} + +async function toggleReplyComposer(commentId) { + const nextId = openedReplyComposerId.value === commentId ? '' : commentId + openedReplyComposerId.value = nextId + if (!nextId) return + await focusReplyInput(nextId) } watch(() => props.tierListId, loadComments, { immediate: true }) @@ -254,6 +280,7 @@ onBeforeUnmount(() => {