-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat] 한 눈에 보기 화면 Compose 마이그레이션 #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
장소의 카테고리를 시각적으로 표시하기 위한 `PlaceCategoryLabel` 컴포저블을 새로 추가했습니다. 이 컴포저블은 아이콘과 텍스트를 조합하여 카테고리 정보를 보여줍니다.
- **`PlaceCategoryLabel.kt` 추가:**
- `Card` 컴포저블을 기반으로 하여, 아이콘과 카테고리명을 `Row`로 묶어 표시합니다.
- `iconColor`를 파라미터로 받아, 배경색을 해당 색상의 10% 투명도를 가진 색으로 동적으로 설정합니다.
- `PlaceCategoryUiModel`을 받아 아이콘 리소스(`getIconId`)와 텍스트 리소스(`getTextId`)를 결정합니다.
- `@Preview`를 추가하여 UI 컴포넌트를 시각적으로 확인할 수 있도록 했습니다.
- **`PlaceListScreen.kt` 추가:**
- 향후 장소 목록 화면을 구성하기 위한 비어 있는 `PlaceListScreen` 컴포저블 파일을 추가했습니다.
세 가지 상태(전체 확장, 절반 확장, 축소)를 가지는 `PlaceListBottomSheet` 컴포저블을 새로 추가했습니다. 이 컴포저블은 `AnchoredDraggable`을 기반으로 구현되어, 사용자가 드래그하거나 내부 컨텐츠를 스크롤할 때 BottomSheet의 높이를 조절할 수 있습니다.
- **`PlaceListBottomSheet.kt` 신규 파일 추가**
- `EXPANDED`, `HALF_EXPANDED`, `COLLAPSED` 세 가지 상태를 정의하는 `PlaceListBottomSheetState` enum을 추가했습니다.
- `AnchoredDraggableState`를 사용하여 세 가지 상태에 대한 앵커(위치)를 설정하고, 드래그 제스처를 처리합니다.
- `NestedScrollConnection`을 구현하여 BottomSheet 내부의 스크롤과 BottomSheet 자체의 드래그 동작이 자연스럽게 연동되도록 했습니다. 예를 들어, 리스트의 최상단에서 위로 스크롤하면 BottomSheet가 확장됩니다.
- 기본 스타일(`shape`, `color`)과 상단에 표시되는 기본 드래그 핸들(`DefaultDragHandle`)을 `PlaceListBottomSheetDefault` 객체에 정의하여 제공합니다.
- 사용자가 직접 커스텀 `dragHandle`과 `content`를 람다로 전달하여 BottomSheet의 내용을 구성할 수 있습니다.
지도 화면 하단에 표시될 장소 목록 UI(`PlaceListScreen`)를 `BottomSheet`와 함께 Compose로 구현했습니다. - **`PlaceListScreen.kt` 신규 추가** - `BottomSheet`를 사용하여 전체 장소 목록을 표시하는 `PlaceListScreen` 컴포저블을 구현했습니다. - `LazyColumn`을 사용해 장소 목록을 효율적으로 렌더링하고, 각 아이템(`PlaceListItem`)은 장소 이미지, 카테고리 라벨, 제목, 설명, 위치 정보를 포함합니다. - 목록을 아래로 당기면 "전체 장소 목록" 핸들이 나타나고, 위로 스크롤하면 장소 리스트가 표시됩니다. - **`PlaceMapScreen.kt` 수정** - `PlaceListScreen`과 `PlaceCategoryScreen`을 통합하여 `PlaceMapScreen`의 전체적인 레이아웃을 구성했습니다. - `PlaceMapScreen`의 파라미터를 추가하고, 실제 UI 구성을 담당하는 `PlaceMapContent`를 내부 private 함수로 분리했습니다. - Preview를 추가하여 UI를 쉽게 확인할 수 있도록 개선했습니다. - **`PlaceCategoryLabel.kt` 수정** - 각 카테고리별로 고유한 라벨 색상을 가지도록 `getLabelColor()`를 사용해 `iconColor`의 기본값을 설정했습니다.
장소 카테고리(`PlaceCategoryUiModel`)에 따라 고유한 라벨 색상을 반환하는 확장 함수 `getLabelColor()`를 추가했습니다. 이 함수는 추후 마커 라벨 등에 각 카테고리를 시각적으로 구분하는 색상을 적용하기 위해 사용됩니다.
- **`PlaceCategoryUiModel.kt` 수정:**
- `getLabelColor()` 확장 함수를 새로 추가했습니다.
- `when` 표현식을 사용하여 각 카테고리(`BOOTH`, `FOOD_TRUCK`, `BAR`)에 해당하는 특정 `Color` 값을 반환하도록 구현했습니다.
지도 화면 하단의 장소 목록(PlaceList) BottomSheet의 UI/UX를 개선하고, 비동기 데이터 로딩 상태를 처리하는 등 관련 로직을 전반적으로 리팩토링했습니다.
- **`PlaceListScreen.kt` 주요 변경사항:**
- `placesUiState`(`PlaceListUiState`)를 도입하여 장소 목록의 로딩, 성공, 에러 상태를 명시적으로 처리하도록 개선했습니다.
- 로딩 중에는 `LoadingStateScreen`, 데이터가 없거나 에러 발생 시에는 `EmptyStateScreen`을 표시합니다.
- 지도 영역에 현재 위치 버튼(`CurrentLocationButton`)과 현 지도 범위 벗어났을 때 초기 위치로 돌아가는 버튼(`BackToPositionButton`)을 추가했습니다.
- BottomSheet의 스크롤 위치(`offset`)에 따라 버튼들의 노출 여부와 위치가 동적으로 변경되도록 `OffsetDependentBox`를 구현했습니다.
- **`PlaceListBottomSheet.kt` 리팩토링:**
- `AnchoredDraggableState`를 외부에서 주입받도록 변경하여 상태 관리의 유연성을 높였습니다.
- BottomSheet의 높이가 동적으로 계산되도록 `layout` Modifier를 사용하여 `updateAnchors`를 호출하는 방식으로 개선했습니다.
- 스크롤 오프셋 값을 외부로 전달하는 `onScroll` 콜백을 추가했습니다.
- **신규 컴포저블 추가:**
- `BackToPositionButton.kt`: '학교로 돌아가기' 등 특정 위치로 돌아가는 기능을 수행하는 `AssistChip` 기반 버튼입니다.
- `CurrentLocationButton.kt`: Naver 지도의 `LocationButtonView`를 Compose 환경에서 사용할 수 있도록 감싼 컴포저블입니다.
- `OffsetDependentBox.kt`: 컨텐츠의 Y축 위치를 외부의 `offset` 값에 따라 동적으로 조절하는 커스텀 레이아웃 컴포저블입니다.
기존의 `Fragment`와 `RecyclerView` 기반으로 구현되었던 장소 목록 UI(`PlaceListFragment`)를 Jetpack Compose 기반의 `PlaceListScreen`으로 전면 마이그레이션했습니다. 이를 통해 XML 레이아웃과 `BottomSheetBehavior` 등 View 시스템에 대한 의존성을 제거하고, 선언적 UI 방식으로 전환했습니다.
- **`PlaceListFragment.kt` 리팩토링:**
- `onCreateView`에서 `ComposeView`를 반환하도록 변경하고, 내부에 `PlaceListScreen` 컴포저블을 설정했습니다.
- 기존의 `RecyclerView.Adapter`, `BottomSheetBehavior` 관련 로직, 스켈레톤 UI 처리 등 View 바인딩 코드를 모두 제거했습니다.
- `PlaceMapViewModel`과 `PlaceListViewModel`의 데이터를 `StateFlow`로 변환하여 구독하고, `PlaceListScreen`의 상태로 전달하도록 수정했습니다.
- 지도 클릭 시 `BottomSheet`를 축소시키는 로직을 `LaunchedEffect` 내에서 Flow를 구독하여 처리하도록 변경했습니다.
- **`PlaceMapViewModel.kt` 수정:**
- `LiveData`로 관리되던 `isExceededMaxLength`와 `onMapViewClick`을 `StateFlow`와 `Flow`로 각각 변환 (`isExceededMaxLengthFlow`, `onMapViewClickFlow`) 하여 Compose에서 효율적으로 상태를 관찰할 수 있도록 했습니다.
- **`PlaceListViewModel.kt` 수정:**
- 장소 목록 상태(`places`)를 `LiveData`에서 `StateFlow`(`placesFlow`)로 변환하여, 하위 컴포저블이 상태 변화를 구독하도록 개선했습니다.
불필요해진 `Complete` UI 상태를 제거하고 관련 로직을 정리하여 장소 목록 화면의 상태 관리 코드를 간소화했습니다.
- **`PlaceListUiState.kt` 수정:**
- 더 이상 사용되지 않는 `Complete` 상태 클래스를 `PlaceListUiState` 실드 인터페이스에서 삭제했습니다.
- **`PlaceListScreen.kt` 수정:**
- `Complete` 상태를 처리하던 분기문을 제거했습니다.
- 이제 `Success` 상태에서 데이터를 변수에 저장한 후, 별도의 분기 없이 바로 `PlaceListContent` 컴포저블을 호출하여 목록을 표시하도록 로직을 변경했습니다.
- **`PlaceListFragment.kt` 및 `PlaceListViewModel.kt` 정리:**
- `Complete` 상태로 변경하던 `setPlacesStateComplete()` 메서드 호출부와 선언부를 모두 제거하여 관련 코드를 정리했습니다.
장소 목록 화면(`PlaceListScreen`)의 데이터 로딩 및 상태 표시 로직을 리팩토링하여 코드 구조를 개선하고 사용자 경험을 향상했습니다.
- **`PlaceListScreen.kt` 수정:**
- `onPlaceLoad` 콜백을 `@Composable` 함수 타입으로 변경하여, `LaunchedEffect`를 통해 시간 태그(`TimeTag`) 변경 시에만 데이터 로딩(`updatePlacesByTimeTag`)이 호출되도록 수정했습니다.
- 데이터 로딩 성공(`Success`) 상태이지만 목록이 비어있는 경우 `EmptyStateScreen`을 표시하도록 하여, 데이터가 없을 때의 UI를 명확히 했습니다.
- `Loading` 및 `Error` 상태 화면의 Y축 오프셋 값을 하드코딩된 `(-220).dp`에서 `HALF_EXPANDED_OFFSET` 상수로 대체하여 가독성과 유지보수성을 높였습니다.
- `Success` 상태에서 불필요하게 `loadedPlace` 상태 변수에 데이터를 저장하던 중간 과정을 제거하고, `placesUiState.value`를 `PlaceListContent`에 직접 전달하도록 간소화했습니다.
- **`PlaceListFragment.kt` 수정:**
- `PlaceListScreen`의 `onPlaceLoad`가 `@Composable`로 변경됨에 따라, `LaunchedEffect` 내에서 `selectedTimeTagFlow`를 구독하여 시간 태그가 변경될 때마다 장소 목록을 업데이트하도록 로직을 수정했습니다.
- 더 이상 사용되지 않는 `timeTag` 상태 변수를 제거했습니다.
`PlaceListFragment`의 Compose 마이그레이션이 완료됨에 따라, 기존 View 시스템에서 사용되던 관련 클래스들을 모두 삭제했습니다.
- **삭제된 클래스 목록:**
- **`PlaceListAdapter` 및 `PlaceViewHolder`**: 장소 목록을 표시하기 위해 `RecyclerView`에서 사용되던 어댑터와 뷰홀더를 제거했습니다.
- **`PlaceListBottomSheetBehavior` 및 관련 `Behavior` 클래스**: `CoordinatorLayout`과 함께 BottomSheet의 복잡한 스크롤 및 상호작용을 처리하던 커스텀 `Behavior`들을 모두 삭제했습니다.
- `PlaceListBottomSheetBehavior`
- `PlaceListScrollBehavior`
- `PlaceListBottomSheetFollowBehavior`
- `BottomSheetFollowCallback`
- `MoveToInitialPositionCallback`
- **`PlaceListBottomSheetCallback`**: BottomSheet의 상태 변화를 감지하던 콜백 클래스를 제거했습니다.
기존 `CoordinatorLayout`과 `BottomSheetBehavior`를 사용하던 장소 목록 UI를 100% Jetpack Compose로 마이그레이션했습니다. 이를 통해 XML 레이아웃과 커스텀 Behavior에 대한 의존성을 제거하고, 상태 관리를 Compose 방식으로 통합하여 코드의 일관성과 유지보수성을 향상했습니다.
- **`PlaceListBottomSheet` 리팩토링:**
- `AnchoredDraggableState`를 직접 다루는 대신, 이를 래핑하는 `PlaceListBottomSheetState` 클래스를 새로 도입하여 상태 관리 로직을 캡슐화했습니다.
- `rememberAnchoredState`를 `rememberPlaceListBottomSheetState`로 대체하여 BottomSheet의 상태를 보다 명확하게 생성 및 관리하도록 개선했습니다.
- `PlaceListBottomSheetState` 열거형의 이름을 `PlaceListBottomSheetValue`로 변경하여 상태 값임을 명확히 했습니다.
- **XML 레이아웃 및 커스텀 Behavior 제거:**
- `fragment_place_list.xml`에서 `PlaceListBottomSheetBehavior`와 `PlaceListBottomSheetFollowBehavior` 등 커스텀 Behavior와 관련된 속성들을 모두 삭제했습니다.
- 이에 따라 더 이상 사용되지 않는 `PlaceListBottomSheetFollowBehavior`와 관련 확장 함수(`placeListBottomSheetFollowBehavior`)를 코드에서 제거했습니다.
- `FestaBookAppGraph`에서 `PlaceListBottomSheetBehavior` 관련 의존성 주입 코드를 삭제했습니다.
- **컴포저블 구조 개선:**
- `PlaceListScreen.kt`:
- `OffsetDependentBox`의 이름을 `OffsetDependentLayout`으로 변경하여 역할을 더 명확히 했습니다.
- `CurrentLocationButton`과 `BackToPositionButton`이 `OffsetDependentLayout` 내에서 `Box`로 감싸져 올바르게 배치되도록 수정했습니다.
- `LazyColumn`에서 장소 목록이 비어있을 때 `EmptyStateScreen`을 `item`으로 추가하여, 목록의 다른 아이템들과 함께 스크롤될 수 있도록 개선했습니다.
- `onBackToInitialPositionClicked` 콜백 함수의 이름을 `onBackToInitialPositionClick`으로 변경하여 일관성을 맞췄습니다.
- `PlaceCategoryLabel.kt`: Row에 적용되던 modifier를 Card의 modifier로 이동시켜 컴포저블의 재사용성을 높였습니다.
- **Fragment 로직 간소화:**
- `PlaceListFragment.kt`:
- `bottomSheetState.animateTo()` 호출을 `bottomSheetState.update()`로 변경하여 새로 도입된 상태 관리 API를 사용하도록 수정했습니다.
- XML 레이아웃의 Behavior를 사용하던 로직을 모두 제거하고 Compose 컴포넌트로 완전히 대체했습니다.
기존에 `AnchoredDraggableState`를 직접 사용하던 `PlaceListBottomSheet`의 상태 관리 방식을 `PlaceListBottomSheetState`라는 새로운 상태 홀더 클래스를 도입하여 개선했습니다. 이를 통해 상태 관련 로직을 캡슐화하고, 컴포저블의 API를 더 명확하게 만들었습니다.
- **`PlaceListBottomSheetState.kt` 신규 추가:**
- `AnchoredDraggableState`를 래핑하는 `PlaceListBottomSheetState` 상태 홀더 클래스와 `rememberPlaceListBottomSheetState` 컴포저블 함수를 추가했습니다.
- `settleImmediately`와 같은 BottomSheet의 동작 관련 로직을 상태 홀더 내부로 이동시켰습니다.
- 상태를 나타내는 `enum class`의 이름을 `PlaceListBottomSheetState`에서 `PlaceListBottomSheetValue`로 변경하여, 상태 홀더 클래스와의 혼동을 방지했습니다.
- **`PlaceListBottomSheet.kt` 리팩토링:**
- `AnchoredDraggableState`를 직접 주입받는 대신, 새로운 `PlaceListBottomSheetState`를 받도록 수정했습니다.
- 상태 업데이트, 오프셋 계산, NestedScroll 연결 등의 로직을 새로운 상태 홀더 객체를 사용하도록 변경했습니다.
- **관련 컴포저블 및 프래그먼트 수정:**
- `PlaceListScreen`과 `PlaceListFragment`에서 `rememberAnchoredState` 대신 `rememberPlaceListBottomSheetState`를 사용하도록 변경했습니다.
- 지도 클릭 시 BottomSheet를 축소시키는 로직을 `bottomSheetState.update()`를 호출하도록 수정했습니다.
- **불필요한 코드 제거:**
- 더 이상 사용되지 않는 `PlaceListBottomSheetBehavior`와 `PlaceListBottomSheetFollowBehavior` 관련 XML 속성 및 의존성 주입 코드를 삭제했습니다.
- 전역 예외 처리기 설정 로직을 주석 처리했습니다. (`FestaBookApp.kt`)
`PlaceListViewModelTest`와 `PlaceMapViewModelTest`에서 불필하거나 더 이상 사용되지 않는 테스트 코드를 정리하고, `StateFlow`의 값을 가져오는 방식을 개선했습니다.
- **`PlaceListViewModelTest.kt` 수정:**
- 장소 정보 로딩 완료 상태(`PlaceListUiState.Complete`)를 검증하던 테스트 메서드를 삭제했습니다. 이는 현재 비즈니스 로직에서 더 이상 필요하지 않은 상태 테스트로 판단되어 제거되었습니다.
- 관련 `PlaceUiModel` import 구문을 제거했습니다.
- **`PlaceMapViewModelTest.kt` 수정:**
- `StateFlow`인 `timeTags`의 값을 검증할 때, 불필요한 `getOrAwaitValue()` 확장 함수 대신 `.value` 프로퍼티를 직접 사용하도록 변경했습니다. 이를 통해 테스트 코드를 더 간결하게 만들었습니다.
S3의 URL 포맷 변경에 대응하고 이미지 로딩 안정성을 높이기 위해, 이미지 URL을 변환하는 확장 함수 `convertImageUrl`을 추가했습니다. 또한, 애플리케이션 전반의 안정성을 강화하기 위해 비활성화되어 있던 전역 예외 처리기를 다시 활성화했습니다.
- **`PlaceListScreen.kt` 수정:**
- `CoilImage`에 이미지를 로드하기 전, `convertImageUrl()` 확장 함수를 호출하여 S3 URL을 올바른 형식으로 변환하도록 수정했습니다.
- **`FestaBookApp.kt` 수정:**
- `onCreate()` 메서드에서 주석 처리되어 있던 `setGlobalExceptionHandler()` 호출을 활성화하여, 앱 전체에서 발생하는 예외를 일관되게 처리하도록 변경했습니다.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
… 버그 해결
장소 목록(`PlaceList`)에서 에러가 발생했을 때 사용자에게 스낵바를 통해 피드백을 제공하는 기능을 추가하고, 데이터 상태에 따른 UI 표시 로직을 개선했습니다.
- **`PlaceListScreen.kt` 수정:**
- 에러 상태를 상위 컴포넌트로 전달하기 위한 `onError` 콜백 파라미터를 추가했습니다. `PlaceListUiState.Error` 상태가 되면 이 콜백이 호출됩니다.
- `PlaceListUiState.Success` 상태일 때, 데이터 목록(`placesUiState.value`)이 비어있는 경우 `EmptyStateScreen`을 표시하도록 로직을 변경했습니다.
- 기존에 `PlaceListContent` 내부 `item`으로 처리되던 빈 상태 UI 로직을 제거하여, 상태 분기점에서 일관되게 처리하도록 구조를 개선했습니다.
- **`PlaceListFragment.kt` 수정:**
- `PlaceListScreen`에 새로 추가된 `onError` 콜백을 구현하여, 에러 발생 시 `showErrorSnackBar()`를 호출해 사용자에게 에러 메시지를 표시하도록 했습니다.
| is PlaceListUiState.Success -> { | ||
| onPlaceLoadFinish(placesUiState.value) | ||
| if (placesUiState.value.isEmpty()) { | ||
| EmptyStateScreen( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
onPlaceLoadFinish의 호출부를 LaunchedEffect로 빼는게 좋을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
딱히 큰 차이는 없을 것 같은데용 저는 이대로 가도 상관 없을 거 같아요
| .layout { measurable, constraints -> | ||
| val placeable = measurable.measure(constraints) | ||
|
|
||
| // 실제 레이아웃 측정 시에만 앵커 설정 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constraints.maxHeight 프로퍼티가 필요하여 layout을 사용했습니다.
현재는 상단 타임태그 바 유무 따라 초기 바텀시트의 높이를 동적으로 조정하는데요. 초기 위치는 그냥 고정시키는게 나은지 의견 부탁드립니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고정시키면 많이 어색한가요?
++어색하지 않다면 구현하기 편한 쪽으로 선택하는게 좋다고 생각합니당.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
개인적으로는 지금처럼 유동적으로 변하는게 조금 어색한 것 같아요 ㅠㅠ
서버에서 빠르게 응답을 받으면 큰 차이는 없지만, 딜레이가 발생하면 깜빡이는것처럼 보여요.
구현 난이도는 큰 차이가 없을 것 같아요. (decorView의 height을 사용하는거라 ratio의 정확도는 떨어집니다. )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저도 다른 상태에 따라 변하는 것보다, 초기 위치를 고정시키는 게 상태를 하나 줄일 수 있어서 좋은 것 같아요.
parkjiminnnn
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생 많이하신 흔적이 보이네요..ㅋㅋ
수고했어요 밀러! 궁금한 점만 코멘트 남겨봤습니다!
| timeTagTitle: String, | ||
| timeTags: List<TimeTag>, | ||
| places: List<PlaceUiModel>, | ||
| modifier: Modifier = Modifier, | ||
| onMapReady: (NaverMap) -> Unit = {}, | ||
| onPlaceClick: (PlaceUiModel) -> Unit = {}, | ||
| onTimeTagClick: (TimeTag) -> Unit = {}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PlaceMapScreen에서는 PlaceMapContent를 호출만 하고 있는데 screen이랑 content랑 따로 분리하신 이유가 있으실까용?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PlaceMapScreen은 추후 하위 Fragment를 제거한 후 사용될 컴포저블 함수입니다 !
지금은 크게 와닿지 않을 수 있지만 컴포저블 함수를 통합할 때, stateFlow 등으로 복잡해질 것 같아요.
해당 부분은 나중에 PlaceMapScreen을 사용하게 될 때 구조가 변경될 가능성이 높아, 가볍게만 봐주셔도 좋을 것 같습니다 !
| Modifier | ||
| .background( | ||
| FestabookColor.white, | ||
| ).padding(horizontal = 24.dp), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
나중에 지도 전용 spacing을 만드는 것도 나쁘지 않을 것 같아용
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PlaceMapScreen에 통합할 때 만들겠습니다 !
| PlaceCategoryUiModel.BOOTH -> Color(0xFF0094FF) | ||
| PlaceCategoryUiModel.FOOD_TRUCK -> Color(0xFF00AB40) | ||
| PlaceCategoryUiModel.BAR -> Color(0xFFFF9D00) | ||
| else -> Color.Unspecified |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
하드 코딩 해치워주세요..!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 부분도 추후 전용 spacing을 만들 때 함께 해치우겠습니다..!
| @Composable | ||
| fun CurrentLocationButton( | ||
| modifier: Modifier = Modifier, | ||
| map: NaverMap? = null, | ||
| ) { | ||
| AndroidView( | ||
| modifier = modifier, | ||
| factory = { context -> LocationButtonView(context) }, | ||
| update = { view -> view.map = map }, | ||
| ) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 친구 KMP할 때 머리좀 아프겠는데요..ㅋㅋ 분기처리해서 해결해야나 혹시 미리 생각해놓으신 방법이 있으신가용?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사실 네이버 지도 컴포넌트는 ios/android 각각의 네이티브 뷰로 만들어야 할 것 같아요..
내부적으로 OpenGL을 쓰고 있어서 통합이 어려울 것 같습니다 ㅜㅜ
스위프트 책 하나 사야겠네요 ㅋㅋ
| content = content, | ||
| modifier = modifier, | ||
| ) { measurables, constraints -> | ||
| val placeable = measurables.first().measure(constraints) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
안전하게 firstOrNull()로 처리하는 것도 좋아보이네용
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반영했습니다 !
| .layout { measurable, constraints -> | ||
| val placeable = measurable.measure(constraints) | ||
|
|
||
| // 실제 레이아웃 측정 시에만 앵커 설정 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고정시키면 많이 어색한가요?
++어색하지 않다면 구현하기 편한 쪽으로 선택하는게 좋다고 생각합니당.
| val bottomSheetBackgroundColor: Color | ||
| @Composable | ||
| get() = FestabookColor.white |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get을 사용하신 이유가 궁금합니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Composable은 함수에만 적용이 가능해서 getter를 사용했습니다.
| is PlaceListUiState.Success -> { | ||
| onPlaceLoadFinish(placesUiState.value) | ||
| if (placesUiState.value.isEmpty()) { | ||
| EmptyStateScreen( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
딱히 큰 차이는 없을 것 같은데용 저는 이대로 가도 상관 없을 거 같아요
`OffsetDependentLayout` 컴포저블에 전달된 `content`가 비어있을 경우(`measurables`가 없을 때) 발생할 수 있는 런타임 예외를 방지하기 위해 안전 처리를 추가했습니다.
- **`OffsetDependentLayout.kt` 수정:**
- `measurables.first()` 대신 `measurables.firstOrNull()`을 사용하여 측정할 요소가 있는지 확인하도록 변경했습니다.
- 요소가 없는 경우 빈 레이아웃을 반환하여 앱이 종료되지 않도록 예외 처리를 구현했습니다.
좋아요! |
etama123
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
밀러 고생하셨어요,,!
| .layout { measurable, constraints -> | ||
| val placeable = measurable.measure(constraints) | ||
|
|
||
| // 실제 레이아웃 측정 시에만 앵커 설정 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저도 다른 상태에 따라 변하는 것보다, 초기 위치를 고정시키는 게 상태를 하나 줄일 수 있어서 좋은 것 같아요.
`CoilImage` 컴포저블 내부에서 `convertImageUrl()` 확장 함수를 직접 호출하도록 변경하여, 이미지 로딩 시 URL 변환 로직을 일관되게 적용하도록 개선했습니다.
- **`CoilImage.kt` 수정:**
- `url` 파라미터를 그대로 사용하던 것을 `url.convertImageUrl()`을 통해 변환된 URL을 사용하도록 수정했습니다.
- **`PlaceListScreen.kt` 수정:**
- `CoilImage` 호출 시 개별적으로 `convertImageUrl()`을 적용하던 코드를 제거하고 원본 URL을 전달하도록 변경했습니다.
|
@parkjiminnnn @etama123 감사합니다. |
#️⃣ 이슈 번호
🛠️ 작업 내용
🙇🏻 중점 리뷰 요청
1. BottomSheet를 커스텀하였습니다.
Material3에서 제공하는 BottomSheetScaffold, ModalBottomSheet 등은 3단 BottomSheet 상태를 제공하지 않아 부득이하게 저수준 API를 활용하여 제작하였습니다. 자세한 사항은 anchoredDraggable 을 참조해주세요
2. 현재 렌더링 성능이 좋지 않습니다.
HWUI 렌더링 보고 결과, PlaceListScreen을 로드할 때, 렌더링이 상당히 오래 걸립니다. 추정 원인으로는 PlaceListBottomSheet의 content 인 것으로 추정됩니다.
에뮬레이터에서 꼭 실행 및 렌더링 시간 측정 부탁드립니다. 릴리즈 빌드로 해주신다면 더 좋습니다.
3. CoilImage 컴포저블에서 url 변환 로직을 넣는 것은 어떻지 제안드립니다.
기존에는 ImageView.load 함수에서, url을 변환하고 있습니다. 이 부분을 혼동 방지를 위해 CoilImage 내부로 이동하는것은 어떨지 제안드립니다.
📸 이미지 첨부 (Optional)