Skip to content

feat: 서재 필터 개발#914

Merged
Sadturtleman merged 11 commits into
developfrom
feat/913
Jul 4, 2026
Merged

feat: 서재 필터 개발#914
Sadturtleman merged 11 commits into
developfrom
feat/913

Conversation

@Sadturtleman

@Sadturtleman Sadturtleman commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

📌𝘐𝘴𝘴𝘶𝘦𝘴

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

서재 필터 UX를 정책에 맞춰 전면 개편했습니다.

헤더

  • 서재 헤더 우측 아이콘을 일반 검색바로 전환

필터 (탭형 바텀시트)

  • 읽기상태 / 장르 / 연재상태 / 별점 / 매력포인트 / 키워드 탭 구성
  • 선택된 필터는 상단에 추가되고 색상 반전 칩으로 표시, 선택된 탭에는 점 표시 및 하단 밑줄 표시
  • 별점: 0.5 단위 슬라이더(햅틱), 선택 구간 강조/딤 처리, 무평점 토글 및 칩 X 초기화
  • 키워드: 등록 키워드 조회·정렬(세계관 > 소재 > 캐릭터 > 관계 > 분위기), 미등록 시 안내 문구
  • 하단 초기화 / 작품 찾기 버튼 UI 정리(모서리·좌우·간격)

보기 / 정렬

  • 그리드뷰 ↔ 리스트뷰 전환, 현재 작품 개수 표시
  • 정렬 전용 바텀시트(picker): 등록 최신순/오래된순, 제목순, 날짜순, 별점 높은순/낮은순(무평점 후처리)

데이터

📷𝘚𝘤𝘳𝘦𝘦𝘯𝘴𝘩𝘰𝘵

KakaoTalk_Photo_2026-07-02-14-43-20 003 KakaoTalk_Photo_2026-07-02-14-43-20 002 KakaoTalk_Photo_2026-07-02-14-43-20 001

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

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features
    • 라이브러리 필터에 장르/연재 상태/평점 범위·무평점·평점 없음, 키워드 선택이 추가되었습니다.
    • 정렬 전용 바텀시트와 검색 상단바를 제공하며, 등록 키워드는 최대 20개까지 선택 가능합니다(초과 시 안내).
    • 평점은 범위 슬라이더와 토글로 조절할 수 있습니다.
  • Bug Fixes
    • 도서 목록 페이징을 커서 기반으로 전환해 다음 페이지 로딩을 안정화했습니다.
  • Style
    • 필터/정렬 UI와 칩 디자인(간격, 모서리 라운딩, 말줄임 처리 등)이 개선되었습니다.

@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

서재 필터를 장르, 연재상태, 평점 범위, 키워드로 확장하고, 목록 조회를 커서 기반으로 전환했습니다. 정렬 선택 바텀시트와 탭 기반 필터 바텀시트가 추가되었고, 저장·조회·표시 모델이 새 구조에 맞게 갱신됐습니다.

Changes

서재 필터 전면 재설계

Layer / File(s) Summary
도메인 필터 모델
domain/library/.../model/Genre.kt, Genres.kt, SeriesStatus.kt, SeriesStatuses.kt, RatingFilter.kt, Keyword.kt, Keywords.kt, SortCriteria.kt
Genre, SeriesStatus, Keywords, RatingFilter와 선택 상태 래퍼가 추가되고, SortCriteria의 키 값과 항목 구성이 갱신됐습니다.
저장 계약과 네트워크 DTO
data/library/.../filter/model/LibraryFilter.kt, FilterRepository.kt, LibraryRepository.kt, datasource/LibraryRemoteDataSource.kt, model/LibraryKeywordEntity.kt, model/NovelEntity.kt, core/network/.../LibraryApi.kt, model/response/*, core/datastore/.../DefaultLibraryFilterDataSource.kt, mapper/LibraryFilterMapper.kt, model/LibraryFilterPreferences.kt
LibraryFilter와 저장소 계약이 새 필터 필드와 커서 조회에 맞게 바뀌고, 키워드/커서 DTO와 API 엔드포인트가 추가·갱신됐습니다.
커서 기반 페이징과 리포지토리
data/library/.../paging/LibraryPagingSource.kt, repository/MyLibraryRepository.kt, repository/UserLibraryRepository.kt
페이징 키가 Long에서 String 커서로 바뀌고, 리포지토리들이 새 필터 파생값과 등록 키워드 조회를 사용하도록 수정됐습니다.
UI 상태와 ViewModel
feature/library/.../model/LibraryFilterUiModel.kt, LibraryViewModel.kt, core/common/.../ComposeExtension.kt
필터 UI 모델이 새 선택 상태를 담도록 바뀌고, ViewModel이 등록 키워드 로딩, 키워드 제한 이벤트, 새 필터 변경 메서드, 정렬 갱신, 필터 검색 호출을 처리하도록 확장됐습니다.
필터 UI 컴포넌트
feature/library/.../filter/LibraryFilterTab.kt, filter/component/LibraryFilterChip.kt, LibraryFilterTabRow.kt, LibraryFilterSelectedChips.kt, LibraryFilterBottomSheetGenre.kt, LibraryFilterBottomSheetSeriesStatus.kt, LibraryFilterBottomSheetRating.kt, LibraryFilterBottomSheetKeyword.kt, RatingRangeSlider.kt, LibraryFilterBottomSheetScreen.kt
탭, 칩, 선택 칩, 장르·연재상태·별점·키워드 섹션과 커스텀 평점 범위 슬라이더가 추가되고, 기존 단일 평점 그리는 제거됐습니다. 탭 기반 필터 바텀시트 화면도 함께 재편되었습니다.
화면과 정렬 UI
feature/library/.../component/LibrarySortBottomSheet.kt, LibraryTopBar.kt, LibraryListItem.kt, LibrayFilterTopBar.kt, LibraryScreen.kt, core/resource/.../ic_library_sort_check.xml
정렬 바텀시트와 검색형 상단바가 추가되고, 서재 화면의 시트 상태/콜백 배선, 필터 상단 상태, 목록 아이템 표시가 새 상태 모델에 맞게 갱신됐습니다.

Sequence Diagram(s)

sequenceDiagram
  participant LibraryScreen
  participant LibraryViewModel
  participant MyLibraryRepository
  participant LibraryPagingSource
  participant LibraryRemoteDataSource
  participant LibraryApi

  LibraryScreen->>LibraryViewModel: updateGenre / updateRatingRange / updateKeyword
  LibraryViewModel->>LibraryViewModel: tempFilterUiState 갱신
  LibraryScreen->>LibraryViewModel: searchFilteredNovels()
  LibraryViewModel->>MyLibraryRepository: applyLibraryFilter(...)
  LibraryViewModel->>LibraryPagingSource: invalidate 후 load(cursor)
  LibraryPagingSource->>MyLibraryRepository: getNovels(cursor)
  MyLibraryRepository->>LibraryRemoteDataSource: getUserNovels(cursor, sortType, genres, ratingMin, ratingMax, keywords, ...)
  LibraryRemoteDataSource->>LibraryApi: /users/{userId}/novels/v2 요청
  LibraryApi-->>LibraryRemoteDataSource: UserNovelsResponseDto(nextCursor)
  LibraryRemoteDataSource-->>MyLibraryRepository: UserNovelsEntity
Loading

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • Team-WSS/WSS-Android#705: 라이브러리 필터 저장/매핑 계약을 처음 정리한 변경으로, 이번 DataStore/Mapper 갱신과 직접 연결됩니다.
  • Team-WSS/WSS-Android#728: 같은 서재 필터 조회 기능을 다루며 LibraryViewModel과 관련 필터 UI 쪽을 수정한 변경으로, 이번 ViewModel/UI 재구성과 맞닿아 있습니다.
  • Team-WSS/WSS-Android#732: 서재 필터 저장 모델과 LibraryFilterMapper 갱신을 다룬 변경으로, 이번 저장/변환 경로와 직접 연결됩니다.

Suggested labels: 🍯 [FEAT]

Suggested reviewers: s9hn, m6z1

Poem

🐰 서재 들판에 바람이 분다
장르 칩이 반짝, 별점도 폴짝
커서 한 칸 건너 다음 장으로
키워드가 둥글게 모여 웃고
토끼 발끝엔 새 정렬이 반짝 ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 제목이 서재 필터 개발이라는 주요 변경 사항을 간결하게 요약합니다.
Linked Issues check ✅ Passed 서재 필터 UX 개편, 정렬/키워드/커서 페이징, 도메인 모델 확장이 #913의 요구를 충족합니다.
Out of Scope Changes check ✅ Passed 변경된 UI, 데이터, 리소스는 모두 서재 필터 기능 구현과 연관되어 보여 별도 범위 이탈은 보이지 않습니다.
Description check ✅ Passed 템플릿의 Issues, Work Description, Screenshot, To Reviewers 섹션을 모두 포함하고 있어 설명이 충분히 충족됩니다.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/913

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (4)
feature/library/src/main/java/com/into/websoso/feature/library/LibraryScreen.kt (1)

84-88: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Toast 문구는 문자열 리소스로 분리해 주세요.

Line 87의 하드코딩 문구는 카피 수정이나 번역 대응 시 추적이 어렵습니다. R.string으로 빼두는 편이 유지보수에 낫습니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@feature/library/src/main/java/com/into/websoso/feature/library/LibraryScreen.kt`
around lines 84 - 88, The hardcoded Toast message in LibraryScreen’s keyword
limit event handler should be moved to a string resource. Update the
collectAsEventWithLifecycle block that uses LocalContext.current and
latestKeywordLimitEvent to reference an R.string entry instead of an inline
literal, so the message is easier to maintain and translate.
feature/library/src/main/java/com/into/websoso/feature/library/component/LibraryTopBar.kt (1)

48-50: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

검색 안내 문구도 문자열 리소스로 관리해 주세요.

Line 49 텍스트가 코드에 고정돼 있어 동일 문구 변경과 번역 반영이 번거로워집니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@feature/library/src/main/java/com/into/websoso/feature/library/component/LibraryTopBar.kt`
around lines 48 - 50, The search prompt text in LibraryTopBar is hardcoded, so
move it out of the Text call and into a string resource to make updates and
localization easier. Update the Text in LibraryTopBar to use the corresponding
string resource via the existing Compose resource access pattern, and add a new
resource entry for the “작품을 검색해보세요” copy.
feature/library/src/main/java/com/into/websoso/feature/library/component/LibrarySortBottomSheet.kt (1)

84-107: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

선택 상태를 semantics로도 노출해 주세요.

현재는 배경색과 체크 아이콘으로만 선택 여부를 표현해서 TalkBack 사용자는 현재 정렬 기준을 알기 어렵습니다. 이 행에는 selected 상태와 단일 선택 역할을 함께 실어주는 편이 안전합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@feature/library/src/main/java/com/into/websoso/feature/library/component/LibrarySortBottomSheet.kt`
around lines 84 - 107, The sort option row in LibrarySortBottomSheet is only
visually indicating selection, so TalkBack cannot announce the current state.
Update the Row building this item to expose selection semantics by setting the
selected state and a single-choice role on the clickable container, using the
existing isSelected and onClick setup. Keep the visual behavior unchanged, but
ensure the item’s accessibility metadata reflects that it is a selectable
radio-style option.
feature/library/src/main/java/com/into/websoso/feature/library/LibraryViewModel.kt (1)

61-61: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

novels는 읽기 전용으로만 노출하는 편이 안전합니다.

지금 형태면 ViewModel 밖에서도 value를 직접 덮어쓸 수 있어서 페이징 상태 일관성이 깨질 수 있습니다. private backing property로 감추고 StateFlow만 공개해 두는 쪽이 안전합니다.

제안 코드
-        val novels: MutableStateFlow<PagingData<NovelUiModel>> = MutableStateFlow(PagingData.empty())
+        private val _novels = MutableStateFlow(PagingData.empty<NovelUiModel>())
+        val novels: StateFlow<PagingData<NovelUiModel>> = _novels.asStateFlow()
-                        novels.update { result }
+                        _novels.update { result }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@feature/library/src/main/java/com/into/websoso/feature/library/LibraryViewModel.kt`
at line 61, `LibraryViewModel`의 `novels`가 `MutableStateFlow`로 공개되어 있어 외부에서 상태를
직접 변경할 수 있습니다. `novels`를 private backing property로 숨기고, 외부에는 `StateFlow` 또는 읽기
전용 타입만 노출하도록 `LibraryViewModel`의 선언과 접근 방식을 정리해 페이징 상태가 내부에서만 갱신되게 수정하세요.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt`:
- Around line 35-45: `DefaultLibraryFilterDataSource.libraryFilterFlow` is
silently dropping the legacy `novelRating` field because `Json(ignoreUnknownKeys
= true)` ignores it, which resets saved rating filters after upgrade. Update the
deserialization path in `DefaultLibraryFilterDataSource` /
`LibraryFilterPreferences.toData()` to detect the old schema and map
`novelRating` into `ratingMin` and `ratingMax` before converting to
`LibraryFilter`, preserving existing user settings instead of falling back to
defaults.

In
`@data/library/src/main/java/com/into/websoso/data/filter/repository/UserLibraryFilterRepository.kt`:
- Around line 22-29: UserLibraryFilterRepository의 필터 갱신 로직에서 filterFlow.first()로
현재 값을 미리 읽어온 뒤 나중에 _filterFlow.update로 쓰는 방식은 원자적이지 않으므로,
sortCriteria/isInterested를 반영하는 모든 갱신 경로에서 _filterFlow.update { current ->
current.copy(...) } 형태로 현재 상태를 콜백 안에서 직접 복사하도록 바꾸세요. 즉, savedFilter 같은 사전 계산값을
쓰지 말고 update 블록의 current를 기준으로 필요한 필드만 덮어써서, 정렬 변경과 상세 필터 변경이 서로 유실되지 않게 수정하세요.

In
`@domain/library/src/main/java/com/into/websoso/domain/library/model/RatingFilter.kt`:
- Around line 23-27: The RatingFilter update function is using an expression
body format that violates ktlint and fails CI, so adjust the function
signature/body formatting to satisfy the rule. Update the affected function in
RatingFilter to use either a multiline expression body or convert it to a block
body, keeping the existing copy logic and identifiers like RatingFilter, copy,
and the update method unchanged.
- Around line 20-27: `RatingFilter.setRange()` currently clamps each bound
independently but can still persist an invalid reversed range when `newMin >
newMax`, which then flows into `chipLabel` and request params. Update
`setRange()` in `RatingFilter` to guarantee `min <= max` by either ordering the
two inputs before copying or rejecting reversed input explicitly, while keeping
the existing clamp and `isRatingless = false` behavior.

In
`@domain/library/src/main/java/com/into/websoso/domain/library/model/SortCriteria.kt`:
- Around line 7-16: `SortCriteria.from()` currently only matches the stored key,
so legacy enum names like RECENT and OLD fall back to RECENT; update the lookup
in SortCriteria.from to accept both the enum key and the enum name for backward
compatibility, while keeping RECENT as the default when no match is found.

In
`@feature/library/src/main/java/com/into/websoso/feature/library/filter/component/LibraryFilterChip.kt`:
- Around line 81-95: The LibraryFilterChip composable currently relies only on
visual styling, so add accessibility semantics to the chip’s clickable
container. Update the Box in LibraryFilterChip to expose a selected state for
selected chips and provide an onClickLabel that describes the remove action for
removable chips, using the existing label/onClick behavior as the reference.
Keep the semantics attached to the clickable modifier path so assistive
technologies can distinguish selection state and understand the chip’s action.

In
`@feature/library/src/main/java/com/into/websoso/feature/library/filter/component/LibraryFilterTabRow.kt`:
- Around line 3-28: import ordering in LibraryFilterTabRow is violating ktlint
standard:import-ordering, so reorder the imports to match the project’s standard
grouping and alphabetical order; use the existing imports in
LibraryFilterTabRow.kt as the target set and sort them consistently (including
androidx, com.into, and any other groups) so CI can pass.
- Around line 60-88: The LibraryFilterTabRow tab item currently exposes only a
click action via debouncedClickable, so the selected state is not announced to
accessibility services. Update the tab container in LibraryFilterTabRow to
expose selection semantics by using selectable(selected = isSelected, role =
Role.Tab) or an equivalent Tab-based component, and keep onClick wired through
the same tab item so screen readers and keyboard users can detect the current
selected tab.

In
`@feature/library/src/main/java/com/into/websoso/feature/library/filter/component/RatingRangeSlider.kt`:
- Around line 74-75: The RatingRangeSlider state keeps stale snapped bounds
after the parent resets min/max, so the first drag can send the old minimum
back. Update the remember state for lastMinSnapped and lastMaxSnapped in
RatingRangeSlider to be keyed or otherwise synchronized with the incoming
min/max props, and make sure the onValueChange logic around latestMin/latestMax
uses the refreshed snapped values instead of the previous remembered ones.

---

Nitpick comments:
In
`@feature/library/src/main/java/com/into/websoso/feature/library/component/LibrarySortBottomSheet.kt`:
- Around line 84-107: The sort option row in LibrarySortBottomSheet is only
visually indicating selection, so TalkBack cannot announce the current state.
Update the Row building this item to expose selection semantics by setting the
selected state and a single-choice role on the clickable container, using the
existing isSelected and onClick setup. Keep the visual behavior unchanged, but
ensure the item’s accessibility metadata reflects that it is a selectable
radio-style option.

In
`@feature/library/src/main/java/com/into/websoso/feature/library/component/LibraryTopBar.kt`:
- Around line 48-50: The search prompt text in LibraryTopBar is hardcoded, so
move it out of the Text call and into a string resource to make updates and
localization easier. Update the Text in LibraryTopBar to use the corresponding
string resource via the existing Compose resource access pattern, and add a new
resource entry for the “작품을 검색해보세요” copy.

In
`@feature/library/src/main/java/com/into/websoso/feature/library/LibraryScreen.kt`:
- Around line 84-88: The hardcoded Toast message in LibraryScreen’s keyword
limit event handler should be moved to a string resource. Update the
collectAsEventWithLifecycle block that uses LocalContext.current and
latestKeywordLimitEvent to reference an R.string entry instead of an inline
literal, so the message is easier to maintain and translate.

In
`@feature/library/src/main/java/com/into/websoso/feature/library/LibraryViewModel.kt`:
- Line 61: `LibraryViewModel`의 `novels`가 `MutableStateFlow`로 공개되어 있어 외부에서 상태를 직접
변경할 수 있습니다. `novels`를 private backing property로 숨기고, 외부에는 `StateFlow` 또는 읽기 전용
타입만 노출하도록 `LibraryViewModel`의 선언과 접근 방식을 정리해 페이징 상태가 내부에서만 갱신되게 수정하세요.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: edf463e6-5759-4ab2-b760-aa5f6d887cfe

📥 Commits

Reviewing files that changed from the base of the PR and between 85f7381 and fe34ba7.

📒 Files selected for processing (45)
  • core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/DefaultLibraryFilterDataSource.kt
  • core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/mapper/LibraryFilterMapper.kt
  • core/datastore/src/main/java/com/into/websoso/core/datastore/datasource/library/model/LibraryFilterPreferences.kt
  • core/network/src/main/java/com/into/websoso/core/network/datasource/library/DefaultLibraryDataSource.kt
  • core/network/src/main/java/com/into/websoso/core/network/datasource/library/LibraryApi.kt
  • core/network/src/main/java/com/into/websoso/core/network/datasource/library/model/response/UserNovelKeywordsResponseDto.kt
  • core/network/src/main/java/com/into/websoso/core/network/datasource/library/model/response/UserNovelsResponseDto.kt
  • core/resource/src/main/res/drawable/ic_library_sort_check.xml
  • data/library/src/main/java/com/into/websoso/data/filter/FilterRepository.kt
  • data/library/src/main/java/com/into/websoso/data/filter/model/LibraryFilter.kt
  • data/library/src/main/java/com/into/websoso/data/filter/repository/MyLibraryFilterRepository.kt
  • data/library/src/main/java/com/into/websoso/data/filter/repository/UserLibraryFilterRepository.kt
  • data/library/src/main/java/com/into/websoso/data/library/LibraryRepository.kt
  • data/library/src/main/java/com/into/websoso/data/library/datasource/LibraryRemoteDataSource.kt
  • data/library/src/main/java/com/into/websoso/data/library/model/LibraryKeywordEntity.kt
  • data/library/src/main/java/com/into/websoso/data/library/model/NovelEntity.kt
  • data/library/src/main/java/com/into/websoso/data/library/paging/LibraryPagingSource.kt
  • data/library/src/main/java/com/into/websoso/data/library/repository/MyLibraryRepository.kt
  • data/library/src/main/java/com/into/websoso/data/library/repository/UserLibraryRepository.kt
  • domain/library/src/main/java/com/into/websoso/domain/library/model/Genre.kt
  • domain/library/src/main/java/com/into/websoso/domain/library/model/Genres.kt
  • domain/library/src/main/java/com/into/websoso/domain/library/model/Keyword.kt
  • domain/library/src/main/java/com/into/websoso/domain/library/model/Keywords.kt
  • domain/library/src/main/java/com/into/websoso/domain/library/model/RatingFilter.kt
  • domain/library/src/main/java/com/into/websoso/domain/library/model/SeriesStatus.kt
  • domain/library/src/main/java/com/into/websoso/domain/library/model/SeriesStatuses.kt
  • domain/library/src/main/java/com/into/websoso/domain/library/model/SortCriteria.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/LibraryScreen.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/LibraryViewModel.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/component/LibraryListItem.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/component/LibrarySortBottomSheet.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/component/LibraryTopBar.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/component/LibrayFilterTopBar.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/filter/LibraryFilterBottomSheetScreen.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/filter/LibraryFilterTab.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/filter/component/LibraryFilterBottomSheetGenre.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/filter/component/LibraryFilterBottomSheetKeyword.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/filter/component/LibraryFilterBottomSheetNovelRatingGrid.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/filter/component/LibraryFilterBottomSheetRating.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/filter/component/LibraryFilterBottomSheetSeriesStatus.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/filter/component/LibraryFilterChip.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/filter/component/LibraryFilterSelectedChips.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/filter/component/LibraryFilterTabRow.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/filter/component/RatingRangeSlider.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/model/LibraryFilterUiModel.kt
💤 Files with no reviewable changes (1)
  • feature/library/src/main/java/com/into/websoso/feature/library/filter/component/LibraryFilterBottomSheetNovelRatingGrid.kt

@devfeijoa devfeijoa left a comment

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.

PR 제목 팀 형식과 ktlint 통과 여부 리뷰 요청 전에 확인 부탁드립니다!
물론 간단한 기능이면 스크린샷만으로도 확인 가능하지만요..!
pr 본문이 없어서 어떤 부분들이 수정 되었는지 매번 노션과 피그마를 왔다갔다하며 확인해야해서요 🥲
본문도 의미있게 작성해주시면 감사하겠습니다..🙇🏻‍♀️

@Sadturtleman Sadturtleman changed the title Feat/913 feat: 서재 필터 개발 Jul 1, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
core/common/src/main/java/com/into/websoso/core/common/extensions/ComposeExtension.kt (1)

21-41: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

디바운스 로직 중복 - 공통 헬퍼로 추출 고려

debouncedClickabledebouncedSelectablelastClickTime/interactionSource 상태 관리와 디바운스 조건 로직을 그대로 복제하고 있습니다. 디바운스 정책이 바뀔 경우 두 곳을 모두 수정해야 하는 부담이 있습니다.

♻️ 공통 헬퍼 추출 예시
+@Composable
+private fun rememberDebouncedOnClick(debounceTime: Long, onClick: () -> Unit): () -> Unit {
+    var lastClickTime by remember { mutableLongStateOf(0L) }
+    return {
+        val currentTime = SystemClock.elapsedRealtime()
+        if (currentTime - lastClickTime >= debounceTime) {
+            lastClickTime = currentTime
+            onClick()
+        }
+    }
+}

이후 debouncedClickable/debouncedSelectable 모두에서 이 헬퍼를 사용하도록 리팩터링할 수 있습니다.

Also applies to: 53-77

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@core/common/src/main/java/com/into/websoso/core/common/extensions/ComposeExtension.kt`
around lines 21 - 41, `debouncedClickable` and `debouncedSelectable` are
duplicating the same debounce state and timing logic, so extract that shared
behavior into a common helper in `ComposeExtension.kt`. Refactor the repeated
`lastClickTime` and `MutableInteractionSource` handling into one reusable
function, then have both `debouncedClickable` and `debouncedSelectable` delegate
to it while preserving their current `Modifier` behavior and click/select
callbacks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@core/common/src/main/java/com/into/websoso/core/common/extensions/ComposeExtension.kt`:
- Around line 21-41: `debouncedClickable` and `debouncedSelectable` are
duplicating the same debounce state and timing logic, so extract that shared
behavior into a common helper in `ComposeExtension.kt`. Refactor the repeated
`lastClickTime` and `MutableInteractionSource` handling into one reusable
function, then have both `debouncedClickable` and `debouncedSelectable` delegate
to it while preserving their current `Modifier` behavior and click/select
callbacks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ece5fff3-1240-41a6-b178-bdf8f4cc4418

📥 Commits

Reviewing files that changed from the base of the PR and between 6ca9a85 and dbc7462.

📒 Files selected for processing (5)
  • core/common/src/main/java/com/into/websoso/core/common/extensions/ComposeExtension.kt
  • data/library/src/main/java/com/into/websoso/data/filter/repository/UserLibraryFilterRepository.kt
  • domain/library/src/main/java/com/into/websoso/domain/library/model/SortCriteria.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/filter/component/LibraryFilterTabRow.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/filter/component/RatingRangeSlider.kt
🚧 Files skipped from review as they are similar to previous changes (2)
  • feature/library/src/main/java/com/into/websoso/feature/library/filter/component/LibraryFilterTabRow.kt
  • feature/library/src/main/java/com/into/websoso/feature/library/filter/component/RatingRangeSlider.kt

@Sadturtleman

Copy link
Copy Markdown
Contributor Author

PR 제목 팀 형식과 ktlint 통과 여부 리뷰 요청 전에 확인 부탁드립니다! 물론 간단한 기능이면 스크린샷만으로도 확인 가능하지만요..! pr 본문이 없어서 어떤 부분들이 수정 되었는지 매번 노션과 피그마를 왔다갔다하며 확인해야해서요 🥲 본문도 의미있게 작성해주시면 감사하겠습니다..🙇🏻‍♀️

넵 다음에는 좀더 확인해보겠습니다 lint는 왠지 모르겠는데 제 pc에서는 계속 통과라 뜨네요...

@devfeijoa

Copy link
Copy Markdown
Contributor

pr 본문이 없어서 어떤 부분들이 수정 되었는지 매번 노션과 피그마를 왔다갔다하며 확인해야해서요 🥲 본문도 의미있게 작성해주시면 감사하겠습니다..🙇🏻‍♀️

제가 이렇게 쓴 이유는 노션 링크를 첨부해달라고 쓴 것이 아니라, 적어도 최소한 어떤 요구사항을 반영한 것인지 적어달라고 부탁드린것 이었습니다.
제가 노션 링크를 매번 클릭해서 확인해야 하는것이 아니라요.

  1. 초기화 버튼, 작품 찾기 버튼 형태가 다른데, 피그마 확인 후 반영 부탁드립니다.
  2. 현재 위치하고 있는 탭( 읽기상태, 장르 등등)에 위치하면 밑줄이 떠야하는데 지금 밑줄이 뜨지 않습니다. 확인 부탁드립니다.
  3. '필터 등록 안 한 경우, 현재 왼쪽 사진과 같이 기본적인 필터 메뉴가 정렬됨' 이라는 요구사항이 있는데, 기본적인 필터 메뉴가 피그마나 노션 요구사항에 있는 상태와 다르게 확인됩니다. 해당 스크린샷 첨부해두겠습니다. 확인부탁드립니다.
  4. 더불어서 리뷰 반영한 커밋들을 일일히 찾아보기가 굉장히 어렵네요. 제가 직접 커밋창에 들어가 각각이 어떤 커밋인지 확인해야할 뿐 더러, 어떤 커밋이 어떤 리뷰를 해결한것인지도 내용이 남겨져 있지도 않아서 코드를 작성하지 않은 입장에서 이해하기는 더욱 힘들고요... 따라서 ktlint를 제외한 어떤 리뷰를 반영한건지 알기 어려워 그 부분에 대한 리뷰를 하지 못했습니다.. 양해부탁드립니다🥲
    조금만 더 리뷰어를 배려해서 PR이나 커밋, 해결한 부분들을 적어주시면 감사하겠습니다..🙇🏻‍♀️
Screenshot_20260701_173101

Comment on lines +43 to +52
/**
* 리플 효과가 없고 디바운스(중복 클릭 방지)가 적용된 선택 Modifier
*
* [selected] 상태를 접근성 트리에 노출하므로 탭/라디오처럼 선택 상태가 있는 요소에 사용한다.
*
* @param selected 현재 선택 여부 (스크린리더/키보드에 전달)
* @param debounceTime 클릭 간격 제한 시간 (기본 500ms)
* @param role 접근성 역할 (기본 [Role.Tab])
* @param onClick 선택 시 실행할 로직
*/

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.

이 주석은 의도적으로 남겨두신걸까요? debounceTime 클릭 간격 제한 시간을 기본 500ms 로 둔 기준이 궁금합니다!
그전에 디바운스가 적용된 선택 modifier가 무엇인지 왜 이걸 선택하여 구현하셨는지도 궁금합니다!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

동시에 여러번 클릭시 예기치 못한 오류가 발생할 수 있을 것 같아 Debounce로 클릭시 처리를 방지했고, 500ms로 잡은 이유는 임시로 잡았습니다. 처음 추가된 extension이라 남겨놨습니다.

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.

@Sadturtleman 이제 보았는데, ComposeExtension 이라는 네이밍에 대해서는 약간 의문이 들긴 하네요..🤔
Compose에서 쓰이는 모든 익스텐션을 모아두기엔 범위가 너무 큰 것 같아보이고, Modifier 관련만 모아둔 것처럼 보이는데 modifier 익스텐션이나 혹은 차라리 서재 필터 관련 익스텐션이라고 네이밍 짓는건 어떨까요? 물론 이 부분에 대해서는 팀 컨벤션을 정한 후 수정하는것이 좋아보입니다! 하루의 의견도 궁금해요!

@Sadturtleman

Copy link
Copy Markdown
Contributor Author
  • '필터 등록 안 한 경우, 현재 왼쪽 사진과 같이 기본적인 필터 메뉴가 정렬됨' 이라는 요구사항이 있는데, 기본적인 필터 메뉴가 피그마나 노션 요구사항에 있는 상태와 다르게 확인됩니다. 해당 스크린샷 첨부해두겠습니다. 확인부탁드립니다. 같은 경우에 피그마와 노션이 서로 달라 피그마 우선으로 진행했습니다.
image

@devfeijoa

devfeijoa commented Jul 1, 2026

Copy link
Copy Markdown
Contributor
  • '필터 등록 안 한 경우, 현재 왼쪽 사진과 같이 기본적인 필터 메뉴가 정렬됨' 이라는 요구사항이 있는데, 기본적인 필터 메뉴가 피그마나 노션 요구사항에 있는 상태와 다르게 확인됩니다. 해당 스크린샷 첨부해두겠습니다. 확인부탁드립니다. 같은 경우에 피그마와 노션이 서로 달라 피그마 우선으로 진행했습니다.
image

제가 확인했을때는 노션과 피그마, 그리고 첨부해둔 피그마 스크린샷이 같은 상태인데 혹시 어느 부분이 다른지 알려주실 수 있을까요?
노션과 피그마 둘 다 관심, 읽기상태, 장르, 연재상태, 별점, 그리고 잘렸지만 매력포인트와 키워드까지 가로 스크롤이 되는것처럼 보입니다.
그런데 제가 스크린샷으로 첨부해둔 사진은 하루가 작업한 브랜치에서 에뮬레이터 돌렸을 때, 필터없이 나오는 부분이 관심, 읽기상태, 매력포인트, 별점만 보여서 요청 드린것이었고요! 어느 부분을 제가 놓친것인지 알려주실 수 있을까요?
그리고 노션과 피그마 요구사항이 다르다면 디자인 팀과 기획팀에게 물어보고 요구사항을 확실히 하는것이 좋겠네요~!

@Sadturtleman

Copy link
Copy Markdown
Contributor Author
  • '필터 등록 안 한 경우, 현재 왼쪽 사진과 같이 기본적인 필터 메뉴가 정렬됨' 이라는 요구사항이 있는데, 기본적인 필터 메뉴가 피그마나 노션 요구사항에 있는 상태와 다르게 확인됩니다. 해당 스크린샷 첨부해두겠습니다. 확인부탁드립니다. 같은 경우에 피그마와 노션이 서로 달라 피그마 우선으로 진행했습니다.
image

제가 확인했을때는 노션과 피그마, 그리고 첨부해둔 피그마 스크린샷이 같은 상태인데 혹시 어느 부분이 다른지 알려주실 수 있을까요? 노션과 피그마 둘 다 관심, 읽기상태, 장르, 연재상태, 별점, 그리고 잘렸지만 매력포인트와 키워드까지 가로 스크롤이 되는것처럼 보입니다. 그런데 제가 스크린샷으로 첨부해둔 사진은 하루가 작업한 브랜치에서 에뮬레이터 돌렸을 때, 필터없이 나오는 부분이 관심, 읽기상태, 매력포인트, 별점만 보여서 요청 드린것이었고요! 어느 부분을 제가 놓친것인지 알려주실 수 있을까요? 그리고 노션과 피그마 요구사항이 다르다면 디자인 팀과 기획팀에게 물어보고 요구사항을 확실히 하는것이 좋겠네요~!

https://www.figma.com/design/QLYZA00K5EIozTroOTDYAU/%EC%9B%B9%EC%86%8C%EC%86%8C-%EB%94%94%EC%9E%90%EC%9D%B8?node-id=24269-73344&t=4zgwr55CcfgSub6Y-1 피그마의 서재 탭 그리드 뷰(2-1-1)에서는 읽기 상태 -> 장르 -> 연재 상태 -> 별점 순 이지만 피그마의 서재 탭 리스트 뷰(2-1-1)에서는 읽기 상태 -> 매력 포인트 -> 연재 상태 로 가는것 같습니다. 그래서 일단 notion에 올라와 있는 사진 기준으로 변경하였고 기획 QA 올릴 때 한번 여쭤보려합니다.

@devfeijoa

devfeijoa commented Jul 2, 2026

Copy link
Copy Markdown
Contributor
  • '필터 등록 안 한 경우, 현재 왼쪽 사진과 같이 기본적인 필터 메뉴가 정렬됨' 이라는 요구사항이 있는데, 기본적인 필터 메뉴가 피그마나 노션 요구사항에 있는 상태와 다르게 확인됩니다. 해당 스크린샷 첨부해두겠습니다. 확인부탁드립니다. 같은 경우에 피그마와 노션이 서로 달라 피그마 우선으로 진행했습니다.
image

제가 확인했을때는 노션과 피그마, 그리고 첨부해둔 피그마 스크린샷이 같은 상태인데 혹시 어느 부분이 다른지 알려주실 수 있을까요? 노션과 피그마 둘 다 관심, 읽기상태, 장르, 연재상태, 별점, 그리고 잘렸지만 매력포인트와 키워드까지 가로 스크롤이 되는것처럼 보입니다. 그런데 제가 스크린샷으로 첨부해둔 사진은 하루가 작업한 브랜치에서 에뮬레이터 돌렸을 때, 필터없이 나오는 부분이 관심, 읽기상태, 매력포인트, 별점만 보여서 요청 드린것이었고요! 어느 부분을 제가 놓친것인지 알려주실 수 있을까요? 그리고 노션과 피그마 요구사항이 다르다면 디자인 팀과 기획팀에게 물어보고 요구사항을 확실히 하는것이 좋겠네요~!

https://www.figma.com/design/QLYZA00K5EIozTroOTDYAU/%EC%9B%B9%EC%86%8C%EC%86%8C-%EB%94%94%EC%9E%90%EC%9D%B8?node-id=24269-73344&t=4zgwr55CcfgSub6Y-1 피그마의 서재 탭 그리드 뷰(2-1-1)에서는 읽기 상태 -> 장르 -> 연재 상태 -> 별점 순 이지만 피그마의 서재 탭 리스트 뷰(2-1-1)에서는 읽기 상태 -> 매력 포인트 -> 연재 상태 로 가는것 같습니다. 그래서 일단 notion에 올라와 있는 사진 기준으로 변경하였고 기획 QA 올릴 때 한번 여쭤보려합니다.

노션에도 피그마에도 적혀있듯이 '필터 등록을 안 한 경우'의 요구사항이라 '관심, 읽기상태, 장르, 연재상태, 별점, 그리고 잘렸지만 매력포인트와 키워드까지 가로 스크롤이 되는것'이라고 생각했어요. 그래서 필터없이 나오는 부분이 관심, 읽기상태, 매력포인트, 별점만 보여서 요청 드린것이었고요! 알려주신 피그마의 서재 탭 그리드 뷰(2-1-1)에서는 '필터 등록이 안 한 경우'이고 피그마의 서재 탭 리스트 뷰(2-1-1)에서는 '필터 등록을 한 경우' 처럼 보입니다.
필터 등록을 했으니 요구사항은 '필터 등록을 한 경우' 로 넘어가니 다른 요구사항으로 이해했습니다.
그 요구사항은 “사용자가 선택한 선택란 중 필터 가장 왼쪽에 있는 선택란” 중 외 “보여지는 선택란 제외 선택한 카테고리 갯수”라고 되어있었고요. 그래서 저는 필터 등록하고 선택 된 순으로 순차적으로 먼저 나오고 그 뒤에 필터 등록 안 된 경우가 나오는 것으로 이해를 했습니다. 그래서 저는 아직도

피그마의 서재 탭 그리드 뷰(2-1-1)에서는 읽기 상태 -> 장르 -> 연재 상태 -> 별점 순 이지만 피그마의 서재 탭 리스트 뷰(2-1-1)에서는 읽기 상태 -> 매력 포인트 -> 연재 상태 로 가는것 같습니다.

이 부분이 잘 이해 안가기도 해서, QA 전에 기획팀과 디자인 팀에게 먼저 물어보고 요구사항을 확실하게 하는게 좋을 것 같습니다!
제가 잘 못 이해하는 부분이거나 놓치는 부분일수도 있어서 확실히하는게 좋을 것 같습니다! 스크린샷도 첨부해두었습니다.
더불어 제가 잘못 이해한 부분이나 놓친 부분이 있으면 알려주세요!

스크린샷 2026-07-02 오전 10 47 19

@devfeijoa

devfeijoa commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

초기화 버튼에 초기화 이미지와 글씨 색상이 같아야하는데, 지금은 초기화 이미지는 검정색으로 뜹니다. 확인하고 수정 부탁드립니다!
또한 초기화 버튼에 border-line이 들어가 있는데, 현재는 border-line이 누락되어있네요. 이 부분도 수정 부탁드립니다.
더불어 코멘트가 길어짐에 따라.. 이번 수정사항 반영하면 코드 부분으로 멘션해서 알려주시면 감사하겠습니다!

Screenshot_20260702_113259

@Sadturtleman

Sadturtleman commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author
  • '필터 등록 안 한 경우, 현재 왼쪽 사진과 같이 기본적인 필터 메뉴가 정렬됨' 이라는 요구사항이 있는데, 기본적인 필터 메뉴가 피그마나 노션 요구사항에 있는 상태와 다르게 확인됩니다. 해당 스크린샷 첨부해두겠습니다. 확인부탁드립니다. 같은 경우에 피그마와 노션이 서로 달라 피그마 우선으로 진행했습니다.
image

제가 확인했을때는 노션과 피그마, 그리고 첨부해둔 피그마 스크린샷이 같은 상태인데 혹시 어느 부분이 다른지 알려주실 수 있을까요? 노션과 피그마 둘 다 관심, 읽기상태, 장르, 연재상태, 별점, 그리고 잘렸지만 매력포인트와 키워드까지 가로 스크롤이 되는것처럼 보입니다. 그런데 제가 스크린샷으로 첨부해둔 사진은 하루가 작업한 브랜치에서 에뮬레이터 돌렸을 때, 필터없이 나오는 부분이 관심, 읽기상태, 매력포인트, 별점만 보여서 요청 드린것이었고요! 어느 부분을 제가 놓친것인지 알려주실 수 있을까요? 그리고 노션과 피그마 요구사항이 다르다면 디자인 팀과 기획팀에게 물어보고 요구사항을 확실히 하는것이 좋겠네요~!

https://www.figma.com/design/QLYZA00K5EIozTroOTDYAU/%EC%9B%B9%EC%86%8C%EC%86%8C-%EB%94%94%EC%9E%90%EC%9D%B8?node-id=24269-73344&t=4zgwr55CcfgSub6Y-1 피그마의 서재 탭 그리드 뷰(2-1-1)에서는 읽기 상태 -> 장르 -> 연재 상태 -> 별점 순 이지만 피그마의 서재 탭 리스트 뷰(2-1-1)에서는 읽기 상태 -> 매력 포인트 -> 연재 상태 로 가는것 같습니다. 그래서 일단 notion에 올라와 있는 사진 기준으로 변경하였고 기획 QA 올릴 때 한번 여쭤보려합니다.

노션에도 피그마에도 적혀있듯이 '필터 등록을 안 한 경우'의 요구사항이라 '관심, 읽기상태, 장르, 연재상태, 별점, 그리고 잘렸지만 매력포인트와 키워드까지 가로 스크롤이 되는것'이라고 생각했어요. 그래서 필터없이 나오는 부분이 관심, 읽기상태, 매력포인트, 별점만 보여서 요청 드린것이었고요! 알려주신 피그마의 서재 탭 그리드 뷰(2-1-1)에서는 '필터 등록이 안 한 경우'이고 피그마의 서재 탭 리스트 뷰(2-1-1)에서는 '필터 등록을 한 경우' 처럼 보입니다. 필터 등록을 했으니 요구사항은 '필터 등록을 한 경우' 로 넘어가니 다른 요구사항으로 이해했습니다. 그 요구사항은 “사용자가 선택한 선택란 중 필터 가장 왼쪽에 있는 선택란” 중 외 “보여지는 선택란 제외 선택한 카테고리 갯수”라고 되어있었고요. 그래서 저는 필터 등록하고 선택 된 순으로 순차적으로 먼저 나오고 그 뒤에 필터 등록 안 된 경우가 나오는 것으로 이해를 했습니다. 그래서 저는 아직도

피그마의 서재 탭 그리드 뷰(2-1-1)에서는 읽기 상태 -> 장르 -> 연재 상태 -> 별점 순 이지만 피그마의 서재 탭 리스트 뷰(2-1-1)에서는 읽기 상태 -> 매력 포인트 -> 연재 상태 로 가는것 같습니다.

이 부분이 잘 이해 안가기도 해서, QA 전에 기획팀과 디자인 팀에게 먼저 물어보고 요구사항을 확실하게 하는게 좋을 것 같습니다! 제가 잘 못 이해하는 부분이거나 놓치는 부분일수도 있어서 확실히하는게 좋을 것 같습니다! 스크린샷도 첨부해두었습니다. 더불어 제가 잘못 이해한 부분이나 놓친 부분이 있으면 알려주세요!

스크린샷 2026-07-02 오전 10 47 19

저도 처음에 그렇게 생각했었는데 2번째 사진을 보시면 필터 등록하고 선택한것과 선택하지 않은 것이 그냥 고정 위치로 나오는것 같아서요! 리스트뷰의 연재 상태 칩을 보면 설정을 안했고 그 다음 칩은 선택했는데 순서가 고정인것같습니다

@devfeijoa

devfeijoa commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

리스트 뷰에서 '필력' 일때만 색상이 누락된 것 같습니다. 확인하고 수정 부탁드려요!
이것도 더불어 코멘트가 길어짐에 따라.. 이번 수정사항 반영하면 코드 부분으로 멘션해서 알려주시면 감사하겠습니다!

Screenshot_20260702_114140

@Sadturtleman

Copy link
Copy Markdown
Contributor Author

@devfeijoa 수정했습니다!

Comment on lines +31 to +42
Text(
text = "서재",
style = WebsosoTheme.typography.headline1,
color = Black,
)
Box(
modifier = Modifier
.debouncedClickable(onClick = onSearchClick)
.padding(horizontal = 20.dp, vertical = 8.dp),
) {
Image(
painter = painterResource(id = ic_common_search),
imageVector = ImageVector.vectorResource(id = ic_plus_novel),

@devfeijoa devfeijoa Jul 4, 2026

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.

헤더에 서재 아이콘이 일반검색으로 이동된다고 PR 본문에도 적혀있고, 요구사항도 같은걸로 아는데 왜 다시 서재 아이콘을 헤더에 넣은건지 알 수 있을까요??

@Sadturtleman Sadturtleman merged commit 004b6e0 into develop Jul 4, 2026
1 of 2 checks passed
This was referenced Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: 서재 필터 개발

2 participants