Repository navigation
[GMSS-300] 채팅방 메시지 애니메이션 성능 개선 및 전송 UX 개선 - #74
Merged
Merged
Conversation
- noRippleClickableIfNotNull 대신 noRippleCombinedClickable을 사용해 onClick은 비활성화하고 onLongClick에만 콜백을 연결 - 문서 주석에 길게 눌렀을 때 콜백이 호출됨을 명시
- 전송 즉시 내 메시지 말풍선을 낙관적으로 그리고, 서버 응답에 맞춰 임시 id를 실제 메시지로 교체 - 전송 실패 시 입력칸 복구 대신 실패한 말풍선에 재전송 버튼을 표시하고 ChatRoomViewModel.onRetrySend로 재시도 가능하도록 처리 - GamssSentChatBubble/ChatMessageBubble에 onRetryClick 옵션을 추가해 시간 대신 재전송 버튼을 노출
- ChatMessageAnimation이 메시지 ID 리스트 대신 Message 리스트를 받아 참조 동일성 비교로 불필요한 재매핑을 방지 - markDisplayed()가 SideEffect로 매 리컴포지션마다 호출되어도 메시지 목록이 바뀌지 않았다면 스킵하도록 처리
- 신규 메시지 진입 애니메이션을 부모 SideEffect 대신 아이템 자신의 첫 컴포지션 시점에 판정·기록하도록 변경해 경쟁 상태로 애니메이션이 누락되던 문제 수정 - 다음 캐릭터 답장의 로딩 말풍선을 별도 아이템 대신 메시지 목록에 같은 id로 포함시켜, 실제 메시지로 전환될 때 자리 전체가 사라졌다 재등장하지 않고 내용만 자연스럽게 바뀌도록 개선 - 전송 완료 콜백 대신 마지막 메시지 id 변경을 기준으로 스크롤 로직을 단순화해, 내가 보낸 메시지가 낙관적으로 그려지는 즉시 하단으로 스크롤되도록 수정
- 임시 메시지가 서버 메시지로 바뀌어도 같은 목록 key를 유지하도록 처리 - 초기 메시지는 진입 애니메이션 대상에서 제외하고 새 메시지만 애니메이션되도록 개선 - 답장 로딩 표시와 실제 답장 전환을 바닥 스크롤 판정에 반영
- 새 메시지 등장을 그래픽 레이어 기반 슬라이드·페이드 애니메이션으로 변경 - 기존 메시지 재배치 애니메이션을 제거해 목록 전체 움직임을 줄임 - 하단 이동을 즉시 스크롤로 바꿔 등장 애니메이션과의 프레임 경합을 완화
- 전송 실패한 임시 말풍선을 제거하고 보낸 내용을 입력칸에 되돌리도록 변경 - 실패 메시지 재전송 UI와 관련 상태·콜백을 제거 - 입력값 외부 변경 시 커서를 끝으로 보정하도록 입력바 상태 처리 개선
- displayMessages lazy 초기화를 Compose 메인 스레드 전용으로 명시하고 LazyThreadSafetyMode.NONE 적용 - 치명적 위험 감지 시 전송 중단 후 말풍선/입력값이 원복되는지 검증하는 테스트 추가 - 테스트용 RiskLexiconRepository를 주입 가능하도록 FixedRiskLexiconRepository 및 파라미터 추가
- 메시지 애니메이션 상태를 채팅 목록과 스크롤 상태가 공유하도록 이동 - 바닥을 따라가지 않는 새 메시지를 미리 확인 처리해 뒤늦게 보여도 애니메이션되지 않도록 개선
- 입력값이 외부에서 복구될 때 커서와 한글 조합 상태가 이전 전송 값으로 되살아나지 않도록 동기화 로직을 분리 - 전송 차단·실패로 임시 말풍선이 제거되는 경우 새 메시지 처리와 스크롤 애니메이션 기록을 건너뛰도록 조정
- 로딩 표시가 아닌 실제 최신 답장을 기준으로 토스트 상태를 갱신 - 이미 화면에 보이는 답장은 안내하지 않도록 가시성 판단 유지
seunghee17
marked this pull request as ready for review
September 29, 2026 03:38
- 위험 신호 검사가 끝나기 전에는 낙관적 말풍선을 그리지 않아 CRITICAL 문구가 화면에 노출되는 문제 방지 - 검사 대기 중 사용자가 입력을 바꾼 경우 검사 통과 후에도 입력칸을 덮어쓰지 않도록 처리 - 말풍선 제거 판정을 목록 길이 비교 대신 직전 바닥 아이템의 key 존재 여부로 변경해 안정성 확보 - 화면 밖에서 도착한 메시지를 미리 "본 메시지"로 기록하는 markAlreadySeen 추가
- 전송 응답 대기 중 입력이 바뀐 경우 실패 처리에서 입력칸을 덮어쓰지 않도록 검증 - 테스트 저장소에 전송 응답 지연 장치를 추가해 입력 경합 상황을 재현 - 채팅 메시지 애니메이션의 중복 표시 처리 API 주석을 실제 함수명에 맞게 정리
…to fix/chatting-room
- 채팅방 테스트가 `RiskLexiconRepository`를 직접 주입하도록 정리 - 경고 용어 렉시콘 저장소 생성을 공통 헬퍼로 분리 - 테스트용 ViewModel 팩토리의 불필요한 `RiskLexicon` 매개변수 제거
soyeonLee126
approved these changes
Sep 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
작업 개요
채팅방의 메시지 애니메이션 성능을 개선하고, 메시지 전송 UX를 다듬었습니다.
작업 유형
변경 사항
낙관적 전송 표시
detectRiskInText)를 하고, 통과하면 입력칸을 비우고 임시 id(음수)로 내 말풍선을 그립니다. 서버 응답이 오면 실제 메시지로 교체합니다.isSending으로 중복 전송만 막습니다. 그 사이 사용자가 새로 입력했다면 검사를 통과해도 입력칸을 비우지 않습니다.ChatRoomState.localKeyByMessageId와listKeyOf()를 추가했습니다. 교체되는 순간 아이템이 다시 그려지거나 애니메이션이 다시 돌지 않습니다.전송 실패 시 입력 복구
revertOptimisticSend). 응답을 기다리는 동안 새로 입력했다면 그 입력을 덮어쓰지 않습니다.GamssInputBar: 입력값이 밖에서 바뀌면(비우기, 복구, 글자 수 제한) 커서를 끝에 둡니다. 복구 시 전송 직전의 커서 위치나 한글 조합 범위가 되살아나지 않도록rememberInputFieldValue()로 동기화합니다. 타이핑 중에는 덮어쓰지 않도록, 바깥value가 바뀐 경우에만 맞춥니다.길게 눌러 답장
ChatMessageBubble에서 캐릭터 메시지의 답장 동작을 탭에서 길게 누르기로 바꿨습니다(noRippleCombinedClickable). 짧게 탭하면 아무 동작도 하지 않습니다.메시지 애니메이션 성능
graphicsLayer하나로 슬라이드와 페이드를 처리합니다. 그리기 단계에서만 움직여 매 프레임 재배치가 없고,CompositingStrategy.ModulateAlpha를 써서 오프스크린 레이어도 만들지 않습니다.animateItem)을 제거했습니다. 새 메시지가 올 때마다 보이는 아이템 전부가 움직여 프레임 밀림이 컸습니다.ChatMessageAnimation.claimShouldAnimate). 진입 시 이미 있던 메시지는 애니메이션하지 않습니다.displayMessages). 답장이 공개될 때 자리는 그대로 두고 내용만 바뀝니다.스크롤 및 새 메시지 토스트
markSeen). 그래서 토스트나 스크롤로 뒤늦게 보여도 등장 애니메이션 없이 나타납니다.테스트
listKeyOf가 임시 말풍선 id와 같은지관련 이슈
관련 작업 (Notion)
스크린샷 / 동작 화면
체크리스트
develop으로 설정되어 있다feat:,fix:등)을 따른다리뷰 요청 사항
GamssInputBar의 입력값 동기화가 한글 조합 입력에 영향을 주지 않는지 봐주세요. 특히 빠른 연속 입력과 조합 중 전송 실패 후 이어서 입력하는 경우입니다.