Skip to content

feat : 컬렉션 작품 검색 및 선택 상태 통합 - #948

Open
devfeijoa wants to merge 17 commits into
feat/938from
feat/939
Open

feat : 컬렉션 작품 검색 및 선택 상태 통합#948
devfeijoa wants to merge 17 commits into
feat/938from
feat/939

Conversation

@devfeijoa

@devfeijoa devfeijoa commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

📌𝘐𝘴𝘴𝘶𝘦𝘴

📎𝘞𝘰𝘳𝘬 𝘋𝘦𝘴𝘤𝘳𝘪𝘱𝘵𝘪𝘰𝘯

  • 작품 검색 Paging 흐름을 제공하는 NovelSearchRepository를 구현했습니다.
  • 최초 조회와 다음 페이지 요청 크기를 각각 20개로 설정했습니다.
  • 컬렉션 작품 검색 상태와 선택 작품을 관리하는 ViewModel을 구현했습니다.
  • 검색 버튼과 키보드 검색 동작을 API 요청에 연결했습니다.
  • 동일한 검색어를 다시 검색하면 기존 Paging 데이터를 새로고침하도록 구현했습니다.
  • 검색어가 비어 있으면 검색 요청 없이 빈 Paging 데이터를 반환하도록 처리했습니다.
  • 검색 결과 로딩, 빈 결과 및 네트워크 오류 화면을 구현했습니다.
  • 빈 검색 결과 화면에서 기존 작품 문의 링크로 이동하도록 연결했습니다.
  • 검색 결과 당겨서 새로고침을 지원합니다.
  • 다음 페이지 조회 실패 시 기존 검색 결과를 유지하도록 처리했습니다.
  • 검색 결과에 작품 이미지, 제목, 작가와 추가 버튼을 표시했습니다.
  • 제목은 최대 두 줄로 표시하고 버튼과 16dp 간격을 적용했습니다.
  • 추가·삭제 버튼에 12dp 벡터 아이콘을 적용했습니다.
  • 선택 작품을 검색 결과 상단에 배치하고 검색 결과 목록에서는 중복 노출하지 않도록 구현했습니다.
  • 작품 추가·삭제 시 추가한 작품 개수와 완료 버튼 상태를 실시간으로 갱신합니다.
  • 검색과 서재에서 선택한 작품을 CollectionSelectedNovel 객체로 통합했습니다.
  • 컬렉션 생성 화면의 BackStackEntry를 기준으로 ViewModel을 공유해 검색과 서재 선택 상태를 유지합니다.
  • 서재 네트워크 오류 UI를 컬렉션 공통 컴포넌트로 교체했습니다.

검증

  • ./gradlew :data:novel:compileDebugKotlin :feature:collection:compileDebugKotlin ktlintCheck --console=plain
  • data:novelfeature:collection 모듈 Debug 컴파일 성공
  • ktlint 성공
  • push 전 전체 단위 테스트 및 앱 Debug 빌드 성공

📷𝘚𝘤𝘳𝘦𝘦𝘯𝘴𝘩𝘰𝘵

Screen_recording_20260819_010453.mp4

💬𝘛𝘰 𝘙𝘦𝘷𝘪𝘦𝘸𝘦𝘳𝘴

  • 검색 실행, Paging 결과, 작품 추가·삭제 및 선택 상태 통합 흐름을 확인 부탁드립니다.
  • 최초 조회 실패는 공통 네트워크 오류 화면을 표시하며, 다음 페이지 실패는 기존 목록을 유지합니다.
  • 서재 API에 작가 정보가 없어 서재에서 선택한 작품의 작가 값은 현재 빈 문자열로 관리합니다.
  • 검색 요청은 최초·다음 페이지 모두 20개로 설정했으며, 서버 페이지 중복 여부는 추후 확인 예정입니다.
  • 선택 작품을 컬렉션 생성 화면에 표시하는 연결은 포함하지 않습니다.
  • Base: feat/938
  • Head: feat/939

- `CollectionNovelSearchRoute`: ViewModel의 검색 상태(`selectedNovels`, `submittedQuery`) 및 페이징 데이터를 UI에 전달하는 Route 구현
- `CollectionNovelSearchScreen`: `LazyColumn`을 활용하여 선택된 작품 목록과 페이징 기반 검색 결과 리스트를 통합하여 표시
- `CollectionNovelSearchEmpty`: 검색 결과가 없을 때 노출되는 안내 뷰 구현 및 작품 문의를 위한 외부 링크(`LocalUriHandler`) 연동
- 검색 필드 내 검색 실행(`onSearchClick`) 및 초기화(`onClearClick`) 시의 검색 상태 동기화 로직 추가
- 검색 결과 리스트에서 이미 선택된 작품은 제외하고 표시하도록 필터링 로직 적용
- 데이터 로딩 상태(Loading) 및 네트워크 에러(Error)에 따른 대응 UI 추가
- `CollectionNovelSearchItem.kt`: 검색된 소설과 선택된 소설을 표시하기 위한 공통 `CollectionNovelSearchItem` 컴포저블 및 이를 활용한 `CollectionNovelSearchItem`, `CollectionSelectedNovelItem` 구현
- `ic_collection_novel_add.xml`: 소설 추가 버튼을 위한 플러스(+) 아이콘 리소스 추가
- `ic_collection_novel_delete.xml`: 소설 삭제 버튼을 위한 엑스(x) 아이콘 리소스 추가
- `CollectionSelectedNovel.kt`: 소설 ID, 제목, 작가, 이미지 URL 정보를 포함하는 `CollectionSelectedNovel` 데이터 클래스 정의
- `NovelSearchRepository.kt`: `NovelSearchPagingSource`를 사용하여 작품 검색 결과를 PagingData로 반환하는 `searchNovels` 함수 구현
- 페이징 처리를 위한 `PAGE_SIZE` 상수를 20으로 정의 및 `PagingConfig` 설정 적용
- `CollectionNovelSearchViewModel.kt`: 작품 검색 및 선택 상태 관리를 위한 `CollectionNovelSearchViewModel` 구현
- `searchResults`: 입력된 검색어에 따라 `NovelSearchRepository`로부터 검색 결과를 페이징 데이터로 가져오는 Flow 정의
- `addNovel`/`removeNovel`: 선택된 작품 리스트에 작품을 추가하거나 제거하는 기능 구현
- `toSelectedNovel`: `NovelSearchEntity`를 컬렉션 선택 모델로 변환하는 확장 함수 추가
- `CollectionNetworkError.kt`: 네트워크 로딩 실패 시 노출되는 이미지, 안내 문구 및 재시도 버튼을 포함한 `CollectionNetworkError` 컴포저블 구현
- `CollectionNovelSearchField.kt`: 검색 수행을 위한 `onSearchClick` 콜백 파라미터 추가 및 `BasicTextField`의 `keyboardActions`에 연결
- `CollectionNovelSearchField.kt`: 검색 아이콘 영역에 `clickable` 속성을 추가하여 클릭 시 `onSearchClick`이 호출되도록 수정
- `CollectionNovelSearchField.kt`: 검색 아이콘에 `Role.Button`을 지정하고 `contentDescription`을 추가하여 접근성 개선
- `CollectionLibraryNovelSelectionViewModel.kt`:
    - `selectedNovelIds`를 `selectedNovels`(`List<CollectionSelectedNovel>`)로 변경하여 선택된 작품의 ID뿐만 아니라 제목, 이미지 등의 정보를 함께 관리하도록 수정
    - `toggleNovelSelection`의 파라미터를 `Long`에서 `CollectionLibraryNovelUiModel`로 변경하고, 선택 여부에 따라 리스트 내 객체를 추가/삭제하도록 로직 수정
    - 기존 `setSelectedNovelIds`를 `setSelectedNovels`로 변경하여 초기 선택 상태 설정 방식 수정
    - `CollectionLibraryNovelUiModel`을 `CollectionSelectedNovel` 데이터 모델로 변환하는 확장 함수 `toSelectedNovel` 추가
- `CollectionNovelSearchItem.kt`: 작품 제목의 최대 줄 수를 1줄에서 2줄(`maxLines = 2`)로 변경
- `CollectionNovelSearchItem.kt`: 작품 정보 영역과 액션 버튼 사이에 16dp 간격(`Spacer`) 추가
- `CollectionNovelSearchItem.kt`: import 구문 순서 정렬 및 최적화
@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2c77318b-ac77-4a1e-8570-b1967d0c6592

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devfeijoa
devfeijoa marked this pull request as ready for review August 19, 2026 06:38
@github-actions
github-actions Bot requested review from Sadturtleman, m6z1 and s9hn August 19, 2026 06:39
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
painter = painterResource(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

boolean 값이 여러 인자에 영향을 준다면 Icon component를 2개 만들어 if 처리하는게 더 보기 편할 것 같습니다

}
}

private fun CollectionLibraryNovelUiModel.toSelectedNovel(): CollectionSelectedNovel =

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uimodel에 대한 mapper은 uimodel에 같이 있는것이 보기 편할 것 같습니다

)
}

submittedQuery.isNotBlank() &&

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조건문이 여러 조건으로 구성된 것은 람다로 뽑아서 구성하는게 읽기 편할 것 같습니다

@@ -10,6 +10,7 @@ android {

dependencies {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리뷰남길곳이 마땅치 않아 여기남깁니다. junit을 implementation하는 부분이 꽤 있는데 테스트 코드가 존재하지 않아 기조를 정하는 것이 좋을 것 같습니다

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat : 컬렉션 작품 검색 및 선택 상태 통합

2 participants