diff --git a/docs/20260429_채팅룸액티비티분석정리.md b/docs/20260429_채팅룸액티비티분석정리.md new file mode 100644 index 00000000..e62dea3c --- /dev/null +++ b/docs/20260429_채팅룸액티비티분석정리.md @@ -0,0 +1,210 @@ +# 20260429 채팅룸 액티비티 분석 정리 + +## 개요 +- `ChatRoomActivity` 화면의 UI 구성과 기능 흐름을 빠르게 파악할 수 있도록 분석 내용을 정리한 문서다. +- 범위는 `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt`를 중심으로, 실제 연결된 레이아웃/어댑터/보조 다이얼로그/리포지토리까지 포함한다. +- 본 문서는 구현 계획 문서 형식을 따르며, 하단 `검증 기록`에 근거 확인 과정을 누적한다. + +## 완료 기준 (Acceptance Criteria) +- [x] AC1: `ChatRoomActivity`의 화면 구성이 UI 영역 기준으로 구분되어 문서화되어야 한다. +- [x] AC2: `ChatRoomActivity`의 주요 기능이 사용자 흐름 기준으로 구분되어 문서화되어야 한다. +- [x] AC3: 각 분석 내용은 실제 확인한 파일 경로를 기준으로 정리되어야 한다. +- [x] AC4: 문서 하단에 무엇을 어떻게 확인했는지 검증 기록이 남아야 한다. + +## 작업 체크리스트 +- [x] `docs` 폴더의 기존 문서 형식과 파일명 규칙을 확인한다. +- [x] 오늘 날짜 기준 분석 문서를 생성한다. +- [x] `ChatRoomActivity`의 UI 구성을 영역별로 정리한다. +- [x] `ChatRoomActivity`의 기능 흐름을 사용자 액션 기준으로 정리한다. +- [x] 관련 파일 경로와 검증 기록을 문서에 남긴다. + +## 분석 대상 파일 +### 핵심 파일 +- `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt` +- `app/src/main/res/layout/activity_chat_room.xml` +- `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatMessageAdapter.kt` +- `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRepository.kt` + +### 보조 UI / 기능 파일 +- `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomMoreDialogFragment.kt` +- `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatBackgroundPickerDialogFragment.kt` +- `app/src/main/java/kr/co/vividnext/sodalive/chat/character/detail/gallery/CharacterGalleryViewerDialogFragment.kt` +- `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/CharacterInfo.kt` +- `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomEnterResponse.kt` +- `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatMessage.kt` +- `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/MessageStatus.kt` + +### 메시지 아이템 레이아웃 +- `app/src/main/res/layout/item_chat_user_message.xml` +- `app/src/main/res/layout/item_chat_ai_message.xml` +- `app/src/main/res/layout/item_chat_typing_indicator.xml` +- `app/src/main/res/layout/item_chat_quota_notice.xml` +- `app/src/main/res/layout/fragment_chat_room_more_dialog.xml` + +## UI 구성 정리 +### 1) 헤더 영역 +- 뒤로가기 버튼, 캐릭터 프로필, 캐릭터 이름, 캐릭터 타입 배지, 현재 보유 캔 배지, 더보기 버튼으로 구성된다. +- 캐릭터 정보가 아직 없으면 이름은 비워두고 플레이스홀더 이미지를 사용한다. +- 캐릭터 타입은 `Clone` 또는 `Character`에 따라 배지 문구와 배경이 달라진다. +- 관련 파일: + - `app/src/main/res/layout/activity_chat_room.xml` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt` + +### 2) 배경 표시 영역 +- 화면 전체 뒤에 캐릭터 배경 이미지가 깔리고, 그 위에 딤 오버레이가 덮이는 구조다. +- 배경 표시 여부는 roomId 기준 preference로 관리된다. +- 배경 이미지는 서버 응답의 `backgroundImageUrl`을 우선 사용하고, 없으면 프로필 이미지 fallback을 사용한다. +- 관련 파일: + - `app/src/main/res/layout/activity_chat_room.xml` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt` + +### 3) 안내 배너 영역 +- 안내 아이콘, 안내 문구, 접기 버튼으로 구성된다. +- 안내 문구는 캐릭터 타입에 따라 달라지며, 사용자가 접으면 숨김 상태가 저장된다. +- 관련 파일: + - `app/src/main/res/layout/activity_chat_room.xml` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt` + +### 4) 채팅 메시지 리스트 영역 +- `RecyclerView` 하나에서 사용자 메시지, AI 메시지, 타이핑 인디케이터, 쿼터 안내 카드를 함께 렌더링한다. +- 사용자 메시지는 오른쪽 정렬 말풍선이고, AI 메시지는 왼쪽 정렬 말풍선이다. +- 같은 발신자의 연속 메시지는 그룹화되어 프로필, 이름, 시간 노출이 축소된다. +- 메시지 유형별 UI는 다음과 같다. + - 사용자 메시지: 시간, 상태별 투명도, 실패 시 재전송 버튼 + - AI 텍스트 메시지: 프로필, 이름, 말풍선, 시간 + - AI 이미지 메시지: 4:5 비율 이미지, 잠금 오버레이, 구매 버튼 + - 타이핑 인디케이터: AI 프로필 + 이름 + 점 3개 애니메이션 + - 쿼터 안내 카드: 남은 시간, 안내 문구, 구매 CTA 버튼 +- 관련 파일: + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatMessageAdapter.kt` + - `app/src/main/res/layout/item_chat_user_message.xml` + - `app/src/main/res/layout/item_chat_ai_message.xml` + - `app/src/main/res/layout/item_chat_typing_indicator.xml` + - `app/src/main/res/layout/item_chat_quota_notice.xml` + +### 5) 입력 영역 +- 메시지 입력창과 전송 버튼으로 구성된다. +- 입력값이 비어 있으면 전송 버튼은 비활성화되고, 텍스트가 있으면 활성화된다. +- IME `Send` 액션도 실제 전송 버튼 클릭으로 연결된다. +- 쿼터가 없을 때는 입력 영역이 숨겨진다. +- 관련 파일: + - `app/src/main/res/layout/activity_chat_room.xml` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt` + +### 6) 보조 다이얼로그 영역 +- 더보기 다이얼로그에서는 배경 표시 스위치, 배경 이미지 변경, 대화 초기화 진입을 제공한다. +- 배경 선택 다이얼로그에서는 이미지 그리드와 현재 배경 표시 테두리를 제공한다. +- 구매한 이미지는 전체화면 캐러셀 뷰어에서 확인한다. +- 관련 파일: + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomMoreDialogFragment.kt` + - `app/src/main/res/layout/fragment_chat_room_more_dialog.xml` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatBackgroundPickerDialogFragment.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/character/detail/gallery/CharacterGalleryViewerDialogFragment.kt` + +## 기능 구성 정리 +### 1) 채팅방 진입 및 초기 동기화 +- `roomId`를 인텐트에서 받아 유효성을 확인한다. +- 헤더, 공지, 리스트, 입력창을 초기화한 뒤 로컬 메시지를 먼저 표시한다. +- 이후 `enterChatRoom()`을 호출해 캐릭터 정보, 배경 이미지, 서버 메시지, 쿼터 상태를 동기화한다. +- 관련 파일: + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRepository.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomEnterResponse.kt` + +### 2) 헤더/멤버 정보 갱신 +- 서버에서 받은 `CharacterInfo`로 이름, 프로필, 타입 배지를 갱신한다. +- 별도로 멤버 정보를 조회해 보유 캔 수를 최신값으로 갱신한다. +- 관련 파일: + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/CharacterInfo.kt` + +### 3) 메시지 전송 +- 사용자가 메시지를 입력하고 전송하면 입력창을 비우고 키보드를 내린다. +- 사용자 메시지를 즉시 `SENDING` 상태로 화면과 로컬 DB에 반영한다. +- 서버 전송 성공 시 `SENT` 상태로 바꾸고, 응답에 포함된 AI 메시지를 리스트에 추가한다. +- 실패 시 `FAILED` 상태로 바꾸고 토스트를 노출한다. +- 관련 파일: + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRepository.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatMessage.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/MessageStatus.kt` + +### 4) 전송 실패 재시도 +- 실패한 사용자 메시지는 재전송 버튼이 노출된다. +- 재시도 시 상태를 다시 `SENDING`으로 바꾸고 후속 성공/실패 결과를 다시 반영한다. +- 현재 구현은 실제 API 재호출이 아니라 데모성 성공 시뮬레이션과 AI 답변 추가 흐름을 사용한다. +- 관련 파일: + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatMessageAdapter.kt` + +### 5) 메시지 리스트 관리 및 페이징 +- 새 메시지는 하단에 append되고, 사용자가 하단 근처에 있으면 자동 스크롤된다. +- 리스트 상단에 도달하면 cursor 기반으로 이전 메시지를 서버에서 불러온다. +- 과거 메시지를 prepend할 때는 기존 스크롤 위치를 유지하도록 오프셋을 보정한다. +- 중복 메시지는 `messageId` 기준으로 제거한다. +- 관련 파일: + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRepository.kt` + +### 6) 쿼터 관리 +- `nextRechargeAtEpoch` 값이 있으면 입력창을 숨기고 쿼터 안내 카드를 표시한다. +- 남은 시간은 카운트다운으로 갱신되며, 만료 시 서버에 다시 상태를 조회한다. +- 쿼터 구매가 성공하면 카운트다운/입력 가능 상태와 캔 배지가 즉시 갱신된다. +- 관련 파일: + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRepository.kt` + - `app/src/main/res/layout/item_chat_quota_notice.xml` + +### 7) 유료 메시지 구매 +- 잠긴 AI 이미지 메시지를 누르면 구매 확인 다이얼로그가 열린다. +- 구매 성공 시 해당 메시지를 해금된 서버 응답 데이터로 교체한다. +- 관련 파일: + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRepository.kt` + - `app/src/main/res/layout/item_chat_ai_message.xml` + +### 8) 구매 이미지 보기 +- 접근 권한이 있는 이미지 메시지만 전체화면 갤러리로 열 수 있다. +- 현재 리스트에서 구매 완료된 이미지 URL만 모아 캐러셀의 데이터 소스로 사용한다. +- 관련 파일: + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/character/detail/gallery/CharacterGalleryViewerDialogFragment.kt` + +### 9) 배경 설정 +- 더보기 다이얼로그에서 배경 표시 on/off를 전환할 수 있다. +- 배경 선택 다이얼로그에서 이미지 선택 후 즉시 액티비티 배경에 적용한다. +- 선택한 배경 이미지 ID와 표시 여부는 roomId 기준으로 저장된다. +- 관련 파일: + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomMoreDialogFragment.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatBackgroundPickerDialogFragment.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt` + +### 10) 대화 초기화 +- 더보기 다이얼로그에서 대화 초기화 액션을 누르면 확인 다이얼로그를 띄운다. +- 서버 초기화 요청 성공 후 해당 방의 로컬 preference와 메시지 DB를 정리하고 새 채팅방으로 다시 진입한다. +- 관련 파일: + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomActivity.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRoomMoreDialogFragment.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/chat/talk/room/ChatRepository.kt` + +## 해석 메모 +- `ChatRoomActivity`는 단순 화면 렌더링만 하는 액티비티가 아니라, 채팅방 진입/동기화/입력/과금/설정/초기화까지 모두 오케스트레이션하는 중심 컨트롤러 역할을 한다. +- UI는 헤더/안내/리스트/입력의 4개 주영역으로 단순하지만, 실제 기능은 로컬 DB와 서버 응답, preference, 다이얼로그 흐름이 복합적으로 얽혀 있다. +- 특히 `ChatMessageAdapter`가 사용자 액션을 콜백으로 Activity에 위임하고, Activity가 다시 `ChatRepository`를 통해 데이터 상태를 바꾸는 구조가 핵심이다. + +## 검증 기록 +- 2026-04-29 + - 무엇/왜/어떻게: `ChatRoomActivity`를 빠르게 이해할 수 있도록 UI 구성과 기능 흐름을 문서화하기 위해, 액티비티 본문뿐 아니라 연결된 레이아웃/어댑터/다이얼로그/리포지토리까지 함께 읽고 구조를 교차 확인했다. + - 실행 명령/도구: + - `read(ChatRoomActivity.kt)` + - `read(activity_chat_room.xml, ChatMessageAdapter.kt, ChatRoomMoreDialogFragment.kt, ChatMessage.kt, ChatRepository.kt)` + - `read(item_chat_user_message.xml, item_chat_ai_message.xml, item_chat_typing_indicator.xml, item_chat_quota_notice.xml, fragment_chat_room_more_dialog.xml)` + - `read(CharacterInfo.kt, ChatRoomEnterResponse.kt, MessageStatus.kt, ChatBackgroundPickerDialogFragment.kt, CharacterGalleryViewerDialogFragment.kt)` + - `task(subagent_type="explore", run_in_background=true)` x2 + - `glob(docs/*.md)` + - `read(기존 docs 샘플 2건)` + - `apply_patch` (본 문서 생성) + - 결과: + - `ChatRoomActivity`의 UI를 헤더/배경/안내/메시지 리스트/입력/보조 다이얼로그로 구분할 수 있음을 확인했다. + - 기능 흐름을 초기 진입, 메시지 전송/재시도, 페이징, 쿼터, 유료 메시지 구매, 이미지 보기, 배경 설정, 대화 초기화로 정리했다. + - 기존 `docs` 폴더의 날짜 기반 체크리스트 문서 형식에 맞춰 분석 문서를 추가했다. diff --git a/docs/agent-guides/workflow-docs-commits.md b/docs/agent-guides/workflow-docs-commits.md index 5ac4dd04..2a4d3f88 100644 --- a/docs/agent-guides/workflow-docs-commits.md +++ b/docs/agent-guides/workflow-docs-commits.md @@ -21,6 +21,7 @@ ## 작업 계획 문서 규칙 (docs) - 모든 작업 시작 전에 `docs` 폴더 아래 계획 문서를 먼저 생성하고, 해당 문서를 기준으로 구현한다. +- 연속된 하나의 작업이라면 별도 새 문서를 만들지 말고 기존 계획 문서에 추가 작업으로 이어서 기록한다. - 계획 문서 파일명은 `[날짜]_구현할내용한글.md` 형식을 사용한다. - 날짜는 `YYYYMMDD` 8자리 숫자를 사용한다. - 구현 항목은 기능/작업 단위 체크박스(`- [ ]`)로 작성하고 완료 즉시 `- [x]`로 갱신한다.