Skip to content

feat: 작가 모아보기 기능#826

Merged
devfeijoa merged 3 commits intodevelopfrom
feat/825
Mar 8, 2026
Merged

feat: 작가 모아보기 기능#826
devfeijoa merged 3 commits intodevelopfrom
feat/825

Conversation

@devfeijoa
Copy link
Contributor

@devfeijoa devfeijoa commented Mar 7, 2026

📌𝘐𝘴𝘴𝘶𝘦𝘴

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

  • 작가명 TextView에 밑줄 스타일 적용
  • 작가명 클릭 시 해당 작가명 기반 탐색 검색 화면 이동
  • 탐색 화면 진입 시 전달받은 작가명으로 초기 검색 수행
  • 뒤로가기 시, 원래 작품 정보 화면으로 이동

📷𝘚𝘤𝘳𝘦𝘦𝘯𝘴𝘩𝘰𝘵

Screen_recording_20260308_030830.mp4

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

변경사항

  • 작품 상세 요약 문구에서 작가명을 별도 TextView로 분리
  • 작가명 밑줄 스타일 및 클릭 이벤트 추가
  • 작가명 클릭 시 NormalExploreActivity로 이동
  • 전달받은 작가명으로 초기 검색 수행

구현 이유

기존 UI 배치를 유지하면서 작가명에만 링크 스타일/클릭을 적용하기 위해 요약 정보와 작가명을 분리했습니다.
별도 검색 화면을 추가하지 않고 기존 NormalExploreActivity를 재사용하기 위해 Intent extra로 작가명을 전달해 초기 검색이 실행되도록 구현했습니다.

Summary by CodeRabbit

신규 기능

  • 저자별 검색 기능 추가로 특정 저자의 작품 검색 가능
  • 소설 상세 페이지에서 저자명을 클릭하면 해당 저자의 검색 결과로 이동
  • 저자명에 밑줄 표시로 상호작용 가능한 요소임을 표시

버그 수정

  • 검색 버튼 클릭 및 엔터 키 입력 시 검색 키워드 업데이트 로직 개선

@devfeijoa devfeijoa requested review from Sadturtleman, m6z1 and s9hn March 7, 2026 18:01
@devfeijoa devfeijoa self-assigned this Mar 7, 2026
@devfeijoa devfeijoa added 🍯 [FEAT] 새로운 기능을 개발합니다. [👸 공주 은영] labels Mar 7, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 7, 2026

Walkthrough

작가 클릭 시 해당 작가의 작품을 검색할 수 있는 기능을 구현했습니다. 작품 상세 화면에서 작가 텍스트를 클릭하면 검색 화면으로 이동하여 해당 작가의 작품들을 조회합니다. 상태 저장소를 통해 검색 데이터를 유지합니다.

Changes

Cohort / File(s) Summary
검색 기능 확장
app/src/main/java/com/into/websoso/ui/normalExplore/NormalExploreActivity.kt, app/src/main/java/com/into/websoso/ui/normalExplore/NormalExploreViewModel.kt
검색 기능에 작가 파라미터 지원 추가. SEARCH_AUTHOR 상수 정의, getIntent() 메서드 오버로드, SavedStateHandle을 통한 상태 저장 및 초기 검색 트리거 구현.
작품 상세 화면 작가 상호작용
app/src/main/java/com/into/websoso/ui/novelDetail/NovelDetailActivity.kt, app/src/main/java/com/into/websoso/ui/novelDetail/NovelDetailClickListener.kt
작가 텍스트에 언더라인 스타일 적용, 작가 클릭 핸들러 추가. NovelDetailClickListener 인터페이스에 onAuthorClick() 메서드 추가.
레이아웃 및 데이터 모델 재구성
app/src/main/res/layout/activity_novel_detail.xml, app/src/main/java/com/into/websoso/ui/novelDetail/model/NovelDetailModel.kt
단일 TextView를 작가와 요약 텍스트를 분리한 LinearLayout으로 변경. formattedNovelDetailSummary에서 작가 정보 제거.

Sequence Diagram

sequenceDiagram
    actor User
    participant NovelDetailActivity as Novel Detail<br/>Activity
    participant NovelDetailClickListener as Click<br/>Listener
    participant NormalExploreActivity as Normal Explore<br/>Activity
    participant NormalExploreViewModel as View<br/>Model
    participant SavedStateHandle as Saved<br/>State
    participant UseCase as Use<br/>Case

    User->>NovelDetailActivity: Click Author TextView
    NovelDetailActivity->>NovelDetailClickListener: onAuthorClick(author)
    NovelDetailClickListener->>NormalExploreActivity: getIntent(context, searchAuthor)
    NormalExploreActivity->>NormalExploreViewModel: Create with SavedStateHandle
    NormalExploreViewModel->>SavedStateHandle: Read SEARCH_AUTHOR
    SavedStateHandle-->>NormalExploreViewModel: Return initialSearchWord
    NormalExploreViewModel->>UseCase: updateSearchResult(initialSearchWord)
    UseCase-->>NormalExploreViewModel: Return search results
    NormalExploreViewModel-->>NovelDetailActivity: Display author's novels
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • yeonjeen
  • junseo511

Poem

🐰 작가를 클릭하면 쏙, 화면 날아 검색 창!
상태도 저장되어 잘 기억하고 있네요.
언더라인으로 단장한 작가 이름,
누르는 순간 작품들이 펼쳐져요! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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 PR 제목은 작가 모아보기 기능이라는 핵심 기능을 명확하게 나타내며, 변경사항의 주요 목적과 일치합니다.
Description check ✅ Passed PR 설명은 필수 템플릿의 모든 섹션(이슈 번호, 작업 설명, 스크린샷, 리뷰어 의견)을 포함하고 있으며, 변경사항과 구현 이유를 상세히 기술했습니다.
Linked Issues check ✅ Passed 코드 변경사항이 #825의 요구사항을 충족합니다: 작가 클릭 시 검색 화면 이동 [#825], 초기 검색 수행 [#825], 뒤로가기 시 이전 화면으로 돌아가기 [#825]가 구현되었습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항은 작가 검색 기능 구현과 직접 관련이 있으며, 연결된 이슈 #825의 범위 내에 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/825

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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 and usage tips.

Copy link
Contributor

@Sadturtleman Sadturtleman left a comment

Choose a reason for hiding this comment

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

수고하셨습니다!

Copy link
Member

@m6z1 m6z1 left a comment

Choose a reason for hiding this comment

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

머지 할 브랜치 release/1.6.0 아니고 develop 으로 바꿔주세요!
이미 release/1.6.0 은 배포 됐습니다!

Comment on lines +76 to +77
val searchAuthor = intent.getStringExtra(SEARCH_AUTHOR).orEmpty()
if (searchAuthor.isBlank()) return
Copy link
Member

Choose a reason for hiding this comment

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

savedStateHandle 에 대해서 알아보시고 적용해보셔도 좋을 것 같아요!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

SavedStateHandle을 적용해 초기 검색어를 ViewModel에서 읽고 자동 검색이 수행되도록 수정했습니다. 후에 검색어 변경도 SavedStateHandle에 함께 반영되도록 처리했습니다!
d21937d

@devfeijoa devfeijoa changed the base branch from release/1.6.0 to develop March 8, 2026 06:35
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
app/src/main/java/com/into/websoso/ui/normalExplore/NormalExploreActivity.kt (1)

78-82: 검색어 추출 로직 중복 고려

검색 실행 전에 updateSearchWord를 호출하는 패턴이 두 곳(에디터 액션, 검색 버튼 클릭)에서 동일하게 반복됩니다. 현재 구현은 정상 작동하지만, 향후 유지보수를 위해 헬퍼 함수로 추출하는 것을 고려해볼 수 있습니다.

♻️ 선택적 리팩토링 제안
private fun executeSearch() {
    val searchText = binding.etNormalExploreSearchContent.text?.toString().orEmpty()
    normalExploreViewModel.updateSearchWord(searchText)
    normalExploreViewModel.updateSearchResult(isSearchButtonClick = true)
    binding.etNormalExploreSearchContent.clearFocus()
    hideKeyboard()
}

Also applies to: 113-117

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/java/com/into/websoso/ui/normalExplore/NormalExploreActivity.kt`
around lines 78 - 82, Duplicate logic extracting the search text and calling
normalExploreViewModel.updateSearchWord appears in both the editor action and
the search button click handlers; create a private helper (e.g., executeSearch)
inside NormalExploreActivity that reads
binding.etNormalExploreSearchContent.text?.toString().orEmpty(), calls
normalExploreViewModel.updateSearchWord(searchText) and
normalExploreViewModel.updateSearchResult(isSearchButtonClick = true), then
clears focus on binding.etNormalExploreSearchContent and calls hideKeyboard();
replace the duplicated blocks at the editor action handler and the search button
onClick with a call to this helper.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@app/src/main/java/com/into/websoso/ui/normalExplore/NormalExploreViewModel.kt`:
- Around line 30-31: searchWord currently exposes a MutableLiveData allowing
external mutation; change its public type to LiveData<String> by returning
_searchWord as LiveData (keep private val _searchWord =
MutableLiveData(initialSearchWord) and change val searchWord: LiveData<String>
get() = _searchWord) so only the ViewModel can modify state; if you rely on
two-way data binding, adapt the binding to call a ViewModel update method or use
a separate public MutableLiveData for binding while still encapsulating mutation
logic.

In `@app/src/main/res/layout/activity_novel_detail.xml`:
- Line 163: The author field in the binding
android:text='@{novelDetailViewModel.novelDetailModel.novel.author}' is showing
raw backend data (tools:text was only a preview); confirm whether the backend
already includes the "・ " separator and if not, add formatting either in the
mapping layer or viewmodel before binding—e.g. implement a formatter/mapper
method (e.g., NovelDetailMapper.formatAuthor or
NovelDetailViewModel.getFormattedAuthor) that returns "・ " + author when author
is non-empty and update the binding to use that formatted property instead of
novelDetailModel.novel.author.

---

Nitpick comments:
In
`@app/src/main/java/com/into/websoso/ui/normalExplore/NormalExploreActivity.kt`:
- Around line 78-82: Duplicate logic extracting the search text and calling
normalExploreViewModel.updateSearchWord appears in both the editor action and
the search button click handlers; create a private helper (e.g., executeSearch)
inside NormalExploreActivity that reads
binding.etNormalExploreSearchContent.text?.toString().orEmpty(), calls
normalExploreViewModel.updateSearchWord(searchText) and
normalExploreViewModel.updateSearchResult(isSearchButtonClick = true), then
clears focus on binding.etNormalExploreSearchContent and calls hideKeyboard();
replace the duplicated blocks at the editor action handler and the search button
onClick with a call to this helper.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d8e331a4-4ca0-4685-9baa-0125f66519fd

📥 Commits

Reviewing files that changed from the base of the PR and between ebfd7f6 and d21937d.

📒 Files selected for processing (6)
  • app/src/main/java/com/into/websoso/ui/normalExplore/NormalExploreActivity.kt
  • app/src/main/java/com/into/websoso/ui/normalExplore/NormalExploreViewModel.kt
  • app/src/main/java/com/into/websoso/ui/novelDetail/NovelDetailActivity.kt
  • app/src/main/java/com/into/websoso/ui/novelDetail/NovelDetailClickListener.kt
  • app/src/main/java/com/into/websoso/ui/novelDetail/model/NovelDetailModel.kt
  • app/src/main/res/layout/activity_novel_detail.xml

Comment on lines +30 to 31
private val _searchWord = MutableLiveData(initialSearchWord)
val searchWord: MutableLiveData<String> get() = _searchWord
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

searchWordMutableLiveData를 외부에 노출합니다

다른 속성들(uiState, isSearchCancelButtonVisibility, isNovelResultEmptyBoxVisibility)은 LiveData로 노출하고 있지만, searchWordMutableLiveData를 그대로 반환하여 외부에서 직접 값 변경이 가능합니다. 캡슐화를 위해 LiveData로 변경하는 것이 좋습니다.

🛡️ 수정 제안
-    private val _searchWord = MutableLiveData(initialSearchWord)
-    val searchWord: MutableLiveData<String> get() = _searchWord
+    private val _searchWord = MutableLiveData(initialSearchWord)
+    val searchWord: LiveData<String> get() = _searchWord

Note: 이 변경 시 양방향 데이터 바인딩을 사용하고 있다면 별도 처리가 필요할 수 있습니다.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private val _searchWord = MutableLiveData(initialSearchWord)
val searchWord: MutableLiveData<String> get() = _searchWord
private val _searchWord = MutableLiveData(initialSearchWord)
val searchWord: LiveData<String> get() = _searchWord
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/src/main/java/com/into/websoso/ui/normalExplore/NormalExploreViewModel.kt`
around lines 30 - 31, searchWord currently exposes a MutableLiveData allowing
external mutation; change its public type to LiveData<String> by returning
_searchWord as LiveData (keep private val _searchWord =
MutableLiveData(initialSearchWord) and change val searchWord: LiveData<String>
get() = _searchWord) so only the ViewModel can modify state; if you rely on
two-way data binding, adapt the binding to call a ViewModel update method or use
a separate public MutableLiveData for binding while still encapsulating mutation
logic.

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> onClick.onAuthorClick(novelDetailViewModel.novelDetailModel.novel.author)}"
android:text='@{novelDetailViewModel.novelDetailModel.novel.author}'
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check how author data is mapped and whether it includes the separator

# Search for author field mapping in data layer
rg -n "author" --type=kt -C 3 | grep -E "(author\s*=|\.author)"

# Check if there's any formatting applied to author in mapper or model
ast-grep --pattern $'author = $_'

Repository: Team-WSS/WSS-Android

Length of output: 90


🏁 Script executed:

#!/bin/bash
# Find Kotlin files related to Novel model
fd -e kt | grep -i novel | head -20

Repository: Team-WSS/WSS-Android

Length of output: 1553


🏁 Script executed:

#!/bin/bash
# Search for author field in Kotlin files
rg -n "author" --glob="*.kt" -C 2 | head -100

Repository: Team-WSS/WSS-Android

Length of output: 9775


🏁 Script executed:

#!/bin/bash
# Look for the NovelDetail model/data class
rg -n "data class.*Novel" --glob="*.kt"

Repository: Team-WSS/WSS-Android

Length of output: 6531


🏁 Script executed:

#!/bin/bash
# Read the NovelDetailModel to see the full structure
cat -n app/src/main/java/com/into/websoso/ui/novelDetail/model/NovelDetailModel.kt

Repository: Team-WSS/WSS-Android

Length of output: 3412


🏁 Script executed:

#!/bin/bash
# Read the UI mapper to see how author is transformed
cat -n app/src/main/java/com/into/websoso/ui/mapper/NovelMapper.kt

Repository: Team-WSS/WSS-Android

Length of output: 4049


🏁 Script executed:

#!/bin/bash
# Search for binding adapters that might format author
rg -n "BindingAdapter" --glob="*.kt" -A 5 | grep -B 3 -A 5 "author"

Repository: Team-WSS/WSS-Android

Length of output: 46


🏁 Script executed:

#!/bin/bash
# Look for the layout file to see full context around line 163
cat -n app/src/main/res/layout/activity_novel_detail.xml | sed -n '150,180p'

Repository: Team-WSS/WSS-Android

Length of output: 2252


🏁 Script executed:

#!/bin/bash
# Double-check: search for any BindingAdapter that might be applied to author field
rg -n "BindingAdapter" --glob="*.kt" -A 10 | head -150

Repository: Team-WSS/WSS-Android

Length of output: 6879


작가명 앞 구분자 처리 확인 필요

tools:text=" ・ 이보라"는 Android Studio의 디자인 타임 미리보기일 뿐 실제 런타임에 적용되지 않습니다. 현재 코드에서 author 필드는 백엔드에서 받은 값을 그대로 표시하며, 어떤 포매팅이나 구분자 추가 로직이 없습니다. 백엔드에서 순수 작가명만 제공한다면 실제 화면에는 구분자 없이 표시될 것입니다.

다음 중 하나를 확인하세요:

  • 백엔드에서 구분자 포함 여부 확인
  • 필요시 mapper에서 문자열 형식화 로직 추가
  • 또는 tools:text를 실제 런타임 표시와 일치하도록 수정
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/src/main/res/layout/activity_novel_detail.xml` at line 163, The author
field in the binding
android:text='@{novelDetailViewModel.novelDetailModel.novel.author}' is showing
raw backend data (tools:text was only a preview); confirm whether the backend
already includes the "・ " separator and if not, add formatting either in the
mapping layer or viewmodel before binding—e.g. implement a formatter/mapper
method (e.g., NovelDetailMapper.formatAuthor or
NovelDetailViewModel.getFormattedAuthor) that returns "・ " + author when author
is non-empty and update the binding to use that formatted property instead of
novelDetailModel.novel.author.

@devfeijoa devfeijoa merged commit 60f7c25 into develop Mar 8, 2026
2 checks passed
@devfeijoa devfeijoa deleted the feat/825 branch March 10, 2026 04:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[👸 공주 은영] 🍯 [FEAT] 새로운 기능을 개발합니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: 작가 모아보기 기능

3 participants