Skip to content

마이페이지 & 분석리포트 QA 반영#162

Merged
moondev03 merged 19 commits into
developfrom
qa/#154-my-페이지-qa-반영
Jul 12, 2026

Hidden character warning

The head ref may contain hidden characters: "qa/#154-my-\ud398\uc774\uc9c0-qa-\ubc18\uc601"
Merged

마이페이지 & 분석리포트 QA 반영#162
moondev03 merged 19 commits into
developfrom
qa/#154-my-페이지-qa-반영

Conversation

@moondev03

@moondev03 moondev03 commented Jul 12, 2026

Copy link
Copy Markdown
Member

작업 내용

  • 마이페이지 UI 구조를 개선하고 뱃지 목록을 그리드 형태로 전환했습니다.
  • 마이페이지에서 뱃지 클릭 시 상세/이동 동작을 추가했습니다.
  • 프로필 화면에서 캐시된 닉네임 우선 노출, 이미지 삭제, 수정 성공 스낵바 등 UX를 보완했습니다.
  • 약관 조회/관리 로직을 동적(Server Driven)으로 정리하고 관련 화면 구조를 개선했습니다.
  • 홈 화면에 큐레이션 API를 연동하고 FAB 및 화면 구조를 개선했습니다.
  • 분석 리포트에서 뒤로가기, 대본 미입력 안내, 작성 유도, 완료 스낵바 등 사용자 흐름을 보완했습니다.
  • PrezelAsyncImage SVG 지원, PrezelTextField 포커스 해제 처리, 그래프 UI 조정 등 공통 컴포넌트를 개선했습니다.
  • 각 수정 항목은 아래 이슈에서 확인

이슈

moondev03 added 19 commits July 10, 2026 21:35
* **feat: `PrezelAsyncImage`의 SVG 이미지 렌더링 지원**
    * `SvgDecoder.Factory()`를 포함하는 커스텀 `ImageLoader`를 구현하여 `AsyncImage`에서 SVG 파일을 로드하고 표시할 수 있도록 개선했습니다.
    * `remember`를 사용하여 `ImageLoader`가 불필요하게 재생성되지 않도록 최적화했습니다.

* **build: Coil SVG 의존성 추가**
    * `libs.versions.toml` 파일에 `coil-kt-svg` 라이브러리 정의를 추가했습니다.
    * `core:designsystem` 모듈의 `build.gradle.kts`에 `coil-kt-svg` 의존성을 추가했습니다.
* **feat: 프로필 이미지 수정 시 삭제 요청 로직 추가**
    * `UserRemoteDataSourceImpl`에서 프로필 이미지 수정 요청 시, 전송할 파일이 없는 경우 `deleteImage` 필드를 `true`로 설정하여 멀티파트 데이터에 포함하도록 수정했습니다.

* **refactor: `MyViewModel` 내 프로필 이미지 상태 반영 로직 수정**
    * 유저 정보 업데이트 시, `profileImageUrl`이 null인 경우 기존 값을 유지하던 엘비스 연산자(`?:`)를 제거하여 서버의 최신 상태(이미지 삭제 포함)가 UI 상태에 즉시 반영되도록 개선했습니다.
* **feat: 프로필 수정 결과에 따른 맞춤형 피드백 메시지 제공**
    * 프로필 수정 완료 후 이전 화면으로 이동할 때, 변경된 항목(이미지, 닉네임, 또는 전체)에 따라 적절한 스낵바 메시지를 표시하는 기능을 추가했습니다.
    * `ProfileUpdateResult` 모델을 정의하고, 결과에 따른 문자열 리소스를 `strings.xml`에 추가했습니다.

* **refactor: `ProfileUiEffect` 및 ViewModel 로직 개선**
    * `ProfileUiEffect.NavigateToBack`을 `data class`로 변경하여 수정 결과(`ProfileUpdateResult`)를 포함할 수 있도록 개선했습니다.
    * `ProfileViewModel`에서 프로필 저장 성공 시 변경 사항을 분석하여 `toProfileUpdateResult()`를 통해 결과를 전달하도록 수정했습니다.

* **refactor: 스낵바 처리를 위한 CoroutineScope 관리 방식 개선**
    * 화면 이동 후에도 스낵바가 안정적으로 표시될 수 있도록 `LocalSnackbarCoroutineScope`를 도입하고 `PrezelApp`에서 이를 제공하도록 수정했습니다.
    * `ProfileScreen`에서 이전 화면으로 돌아가기 직전에 해당 Scope를 사용하여 스낵바를 호출하도록 변경했습니다.

* **style: UI 세부 조정**
    * `ProfileScreen` 하단 버튼 영역(`PrezelButtonArea`)의 배경(`showBackground`)을 `false`로 변경하여 디자인을 조정했습니다.
* **refactor: `submitButtonEnabled` 판단 로직 가독성 개선**
    * 프로필 변경 여부(`hasAnyChanges`)와 닉네임 수정 가능 여부(`isNicknameSubmittable`)를 별도 속성으로 분리하여 버튼 활성화 조건을 명확하게 정의했습니다.
    * 닉네임이 변경되지 않았거나, 변경된 닉네임이 사용 가능한 상태(`Available`)인 경우를 체크하는 로직을 추가하여 안정성을 높였습니다.
* **refactor: `MyScreen` 레이아웃을 `LazyVerticalGrid` 기반으로 변경**
    * 기존 `Column` 내부에 고정되었던 UI 구조를 2열 `LazyVerticalGrid`로 전환하여 뱃지 목록을 그리드 형태로 표시하도록 개선했습니다.
    * `ProfileSection`과 `BadgeListTitle`이 그리드 내에서 전체 너비를 차지하도록 `GridItemSpan(maxLineSpan)`을 적용했습니다.
    * 뱃지 목록의 각 아이템을 처리하는 `BadgeGridItem` 컴포저블을 추가했습니다.

* **refactor: 뱃지 섹션 구성 방식 변경 및 파일 정리**
    * 가로 스크롤 방식(`LazyRow`)을 사용하던 `BadgeSection.kt` 파일을 삭제하고 해당 로직을 그리드 구조에 맞게 `MyScreen`으로 통합했습니다.
    * 뱃지 타이틀 클릭 시 리플 효과가 없는 `noRippleClickable`을 적용하여 인터랙션을 조정했습니다.

* **cleanup: 불필요한 설정 및 어노테이션 제거**
    * 더 이상 사용되지 않는 `ExperimentalMaterial3Api` 어노테이션을 삭제했습니다.
    * 그리드 시스템에 맞춰 패딩 및 간격(`Arrangement.spacedBy`) 설정을 최적화했습니다.
* **refactor: 키보드 상태 변화에 따른 자동 포커스 해제 로직 구현**
    * `WindowInsets.isImeVisible`을 사용하여 소프트웨어 키보드(IME)의 가시성을 감지하는 로직을 추가했습니다.
    * 키보드가 표시된 상태에서 사용자가 키보드를 닫을 경우, `LocalFocusManager`를 통해 텍스트 필드의 포커스를 명시적으로 해제(`clearFocus`)하도록 개선했습니다.
    * 키보드 상태 변화를 추적하기 위해 `wasImeVisible` 상태와 `LaunchedEffect`를 도입했습니다.
    * `ExperimentalLayoutApi` 어노테이션을 추가했습니다.

# Conflicts:
#	Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt
* **feat: `MyScreen` 내 배지 아이템 클릭 기능 구현**
    * `BadgeGridItem`에 `noRippleClickable` 수식어를 적용하여 배지 클릭 시 상세 화면으로 이동하는 `navigateToBadge` 콜백을 연결했습니다.
* **refactor: `DeletionAgreement` 컴포저블 이동 및 레이아웃 수정**
    * `DeleteAccountNoticeStep` 내부에 위치하던 `DeletionAgreement` 컴포저블을 `DeleteAccountScreen`으로 이동했습니다.
    * 탈퇴 안내(`NOTICE`) 단계에서 하단 `DeleteAccountActionSection` 바로 위에 동의 체크박스가 노출되도록 `DeleteAccountScreen`의 레이아웃 구조를 변경했습니다.
    * 체크박스 및 텍스트 영역에 `noRippleClickable`을 적용하여 클릭 시 상태 변경이 용이하도록 개선했습니다.

* **cleanup: `DeleteAccountNoticeStep` 내 불필요한 코드 정리**
    * 더 이상 사용되지 않는 내부 `DeletionAgreement` 함수 정의를 삭제하고 호출부를 주석 처리 또는 제거하여 코드를 정리했습니다.
* **feat: `GetUserNicknameUseCase` 추가**
    * `UserRepository`를 통해 로컬에 저장된 사용자 닉네임을 조회하는 UseCase를 구현했습니다.

* **refactor: `ProfileViewModel` 초기화 로직 및 데이터 로딩 개선**
    * 화면 진입 시 서버 데이터를 가져오기(`fetchUserInfo`) 전, 캐시된 닉네임을 먼저 화면에 표시(`prefillNickname`)하여 사용자 경험을 개선했습니다.
    * `fetchUserInfo` 메서드를 `suspend` 함수로 변경하고 `viewModelScope` 내에서 순차적으로 실행되도록 조정했습니다.

* **refactor: `ProfileUiState` 상태 관리 고도화**
    * 서버 데이터의 동기화 여부를 나타내는 `isHydrated` 플래그를 `Content` 데이터 클래스에 추가했습니다.
    * 캐시 데이터로 초기 상태를 생성하는 `fromCachedNickname` 도우미 함수를 추가했습니다.
    * 서버로부터 최신 데이터를 받아오기 전(`isHydrated = false`)에는 정보 수정 후 저장 버튼이 활성화되지 않도록 `submitButtonEnabled` 로직을 수정했습니다.
* **feat: 서버 기반 약관 조회 기능 및 UseCase 추가**
    * 서버에서 약관 목록을 가져오기 위한 `FetchTermsUseCase`, `TermsRepository.fetchTerms`, `TermsService.fetchTerms`를 추가했습니다.
    * `Term`(Domain), `TermsAgreementUiModel`(UI), `FetchTermsResponse`(Network) 등 관련 데이터 모델을 정의했습니다.
    * 하드코딩되어 있던 약관 데이터(이용약관, 개인정보 정책 등)를 서버에서 받아온 리스트를 처리하는 동적 구조로 변경했습니다.

* **refactor: 약관(Terms) 관련 UI 및 로직 개선**
    * `TermsUiState` 내 개별 체크박스 상태를 `ImmutableList<TermsAgreementUiModel>`로 통합 관리하도록 수정했습니다.
    * `TermsUiIntent`에서 개별 토글 액션을 `ToggleTerm(termsId)`으로 일반화했습니다.
    * `TermsDetailModal` 및 navigation 로직에서 특정 타입 대신 `title`과 `url`을 직접 전달받아 표시하도록 유연화했습니다.
    * `feature:terms:impl` 모듈의 `BuildConfig` 의존성(약관 URL)을 제거했습니다.

* **feat: 뱃지(Badge) 조회 시 정렬 기능 도입**
    * 뱃지 목록 조회 시 정렬 조건을 전달할 수 있도록 `BadgeSortType` 열거형을 추가했습니다.
    * `BadgeRepository`, `BadgeRemoteDataSource`, `BadgeService`에 `sort` 쿼리 매개변수를 추가했습니다.
    * `MyViewModel`에서 내 뱃지 조회 시 획득 순(`ACQUIRED`)으로 정렬하여 가져오도록 수정했습니다.

* **refactor: 설정(Setting) 화면 내 약관 상세 이동 로직 수정**
    * `SettingViewModel`에서 유저 정보와 함께 약관 데이터를 함께 조회하도록 개선했습니다.
    * 설정 화면에서 약관 클릭 시, 로드된 약관 목록에서 제목 매칭을 통해 동적으로 URL을 찾아 상세 화면으로 이동합니다.

* **style: 불필요한 리소스 및 파일 정리**
    * 더 이상 사용하지 않는 `TermsDocumentType` 클래스와 하드코딩된 약관 관련 문자열 리소스들을 삭제했습니다.
* **style: SpeedGraph의 기본 하한값 변경**
    * 그래프의 시각적 범위를 조정하기 위해 `DEFAULT_LOWER_BOUND` 값을 180에서 190으로 변경했습니다.
* **refactor: StickGraph 막대 배경 및 레이아웃 구조 변경**
    * 고정된 높이의 배경 트랙(`STICK_GRAPH_TRACK_HEIGHT`)을 추가하고 `bgMedium` 색상을 적용하여 막대가 비어있는 영역을 시각화했습니다.
    * 데이터 막대를 감싸는 상위 `Box`를 추가하고 `Alignment.BottomCenter`를 적용하여 막대가 아래에서 위로 차오르는 형태로 레이아웃을 수정했습니다.

* **refactor: 막대 높이 계산 공식 수정**
    * 막대의 높이를 계산할 때 기준이 되는 값을 기존 최대값(`maxCount`)에서 전체 항목의 총합(`totalCount`)으로 변경했습니다.
    * 이를 통해 개별 항목이 전체에서 차지하는 비율을 보다 정확하게 시각적으로 나타내도록 개선했습니다.
* **feat: 큐레이션(Curation) 관련 도메인 및 데이터 레이어 추가**
    * `Curation` 도메인 모델과 `GetCurationResponse` 네트워크 응답 모델을 추가했습니다.
    * `PresentationRepository` 및 RemoteDataSource에 `getCuration` 메서드를 구현하고 API 연동을 완료했습니다.
    * `FetchCurationUseCase`를 추가하고, `FetchMainDataUseCase`에서 홈 데이터 조회 시 각 발표별 큐레이션 정보를 함께 포함하도록 수정했습니다.

* **refactor: `LocalAppDimmerState` 기능 확장 및 FAB 로직 개선**
    * `LocalAppDimmerState`에 `foregroundContent` 속성을 추가하여 딤(Dim) 처리 시 그 위에 표시될 별도의 컴포저블 UI를 주입받을 수 있도록 개선했습니다.
    * `HomeAnalysisFabOverlay`에서 기존의 복잡한 `Popup` 및 좌표 측정 로직을 제거하고, `AppDimmer`의 포그라운드 레이어를 사용하여 FAB 확장 메뉴를 표시하도록 단순화했습니다.

* **refactor: 홈 화면 UI 구조 및 레이아웃 최적화**
    * `HomeScreenContent`에 `Scaffold`를 도입하여 상단 바(TopBar)와 FloatingActionButton 배치를 시스템 표준 방식으로 개선했습니다.
    * `MainDataWithPracticeRecords` 및 `PresentationUiModel` 등 홈 관련 UI 모델에 큐레이션 데이터 필드를 추가했습니다.
    * `PrezelApp` 내 `AppDimmerOverlay`가 주입된 포그라운드 콘텐츠를 렌더링할 수 있도록 구조를 변경했습니다.
* **fix: ScriptAnalysisSection 내 에러 정보 컴포넌트 활성화**
    * 전체 에러 횟수를 표시하는 UI 컴포넌트에 `enabled = true` 속성을 추가하여 클릭 상호작용이 정상적으로 동작하도록 수정했습니다.
* **feat: 분석 완료 안내 메시지 스트링 리소스 추가**
    * 분석 리포트 저장 완료를 알리는 `feature_analysis_impl_analyze_complete_message` 스트링을 추가했습니다.

* **feat: 리포트 이동 시 스낵바 표시 로직 구현**
    * `AnalysisFlowUiEffect.NavigateToReport` 효과 발생 시, 리포트 화면 이동과 함께 "분석 리포트가 저장되었어요." 스낵바가 표시되도록 개선했습니다.
    * `LocalSnackbarCoroutineScope`를 사용하여 스낵바를 비동기로 호출하는 로직을 추가했습니다.
* **feat: 분석 리포트 스낵바에 대본 입력 액션 추가**
    * 대본 일치율이나 발화 분석이 불가능한 경우, 스낵바에 '입력하기' 액션 버튼을 노출하도록 개선했습니다.
    * `AnalysisReportUiMessage`에 `requiresScriptInputAction` 확장 프로퍼티를 추가하여 특정 메시지 상황에서만 액션이 활성화되도록 정의했습니다.
    * 스낵바 액션 클릭 시 `AnalysisReportUiIntent.ClickReWriteScript`를 호출하여 대본 작성 화면으로 연결되도록 구현했습니다.

* **refactor: 스낵바 액션 노출 조건 세분화**
    * 리포트가 과거 데이터가 아니고(`isPast == false`), 대본이 아직 작성되지 않은(`isScriptWritten == false`) 상태일 때만 입력 액션이 표시되도록 조건을 추가했습니다.

* **resource: 스낵바 액션용 문자열 리소스 추가**
    * 스낵바 액션 버튼에 사용될 "입력하기"(`feature_report_impl_snackbar_action_input`) 문자열을 추가했습니다.
* **refactor: `DeleteAccountNoticeStep`의 상태 및 콜백 매개변수 삭제**
    * 안내 단계에서 더 이상 사용하지 않는 `isChecked` 및 `onCheckedChange` 매개변수를 제거했습니다.
    * 컴포저블 내부에 주석 처리되어 있던 `DeletionAgreement` 관련 코드를 정리했습니다.

* **refactor: `DeleteAccountScreen` 내 관련 로직 정리**
    * `DeleteAccountContent` 및 `DeleteAccountNoticeStep` 호출부에서 동의 체크와 관련된 상태 전달 로직을 삭제했습니다.
    * 프리뷰 코드의 변경된 매개변수 구조를 반영했습니다.
@moondev03 moondev03 self-assigned this Jul 12, 2026
@moondev03 moondev03 requested a review from HamBeomJoon as a code owner July 12, 2026 11:39
@moondev03 moondev03 added the 🔧 fix 정상 동작해야 하는 기능의 결함 수정 label Jul 12, 2026
@moondev03 moondev03 linked an issue Jul 12, 2026 that may be closed by this pull request
11 tasks
@moondev03 moondev03 merged commit e736779 into develop Jul 12, 2026
2 checks passed
@moondev03 moondev03 deleted the qa/#154-my-페이지-qa-반영 branch July 12, 2026 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔧 fix 정상 동작해야 하는 기능의 결함 수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MY 페이지 QA 반영

2 participants