[FEAT/#270] 임시저장 상태에 따른 분기를 추가합니다.#275
Conversation
- replyStatus 상태를 String → ReplyStatus enum으로 변경하여 타입 안정성 향상 - 일기 상태 판별 로직(canWriteDiary, canReplyDiary, isValidDraftDate) 별도 함수로 분리 - showContinueDraftDialog 상태 플래그 추가 - deleteDiary 시 상태 초기화 로직 추가 (diaryCount, isDeleted, replyStatus)
- HomeRoute에서 selectedYear/Month/Day → selectedDiaryDate, selectedDate로 구조 간소화 - diaryCount, isDeleted → ReplyStatus 기반 분기 처리 개선 - onClickWriteDiary 내부에서 ReplyStatus 기반 이어쓰기 분기 처리 추가 - showContinueDraftDialog 처리 로직 추가
WalkthroughThis update introduces and integrates a draft (임시저장) state for diaries throughout the application's data models, UI, and logic. It adds new enum values, properties, and drawable icons, refactors composable parameters and state management, and updates control flow to handle draft-specific behaviors and user interactions. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant HomeScreen
participant HomeViewModel
User->>HomeScreen: Clicks "Write Diary" button
HomeScreen->>HomeViewModel: Check hasDraft, canWrite, canReply
alt hasDraft and valid draft date
HomeScreen->>User: Show "Continue Draft" dialog
User->>HomeScreen: Confirms continue
HomeScreen->>HomeViewModel: Set dialog state, proceed to draft
else canWrite
HomeScreen->>User: Navigate to diary writing
else canReply
HomeScreen->>User: Navigate to reply
else
HomeScreen->>User: Button disabled
end
Assessment against linked issues
Assessment against linked issues: Out-of-scope changesNo out-of-scope changes found. Possibly related PRs
Suggested labels
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt (1)
273-295: Consider reducing the number of parametersThe
HomeScreencomposable has 16 parameters, which makes it difficult to maintain and test. Consider grouping related parameters into data classes.For example, you could create:
data class HomeScreenState( val calendarState: CalendarState<MonthlyCalendarResponseDto>, val deleteDiaryState: DeleteDiaryState, val showYearMonthPickerState: Boolean, val isError: Boolean, val errorMessage: String, val selectedYear: Int, val selectedMonth: Int, val selectedDate: LocalDate, val hasDraft: Boolean, val canWrite: Boolean, val canReply: Boolean ) data class HomeScreenActions( val onClickDiaryList: (Int, Int) -> Unit, val onClickSetting: () -> Unit, val onClickWriteDiary: (Int, Int, Int) -> Unit, val onClickReplyDiary: (Int, Int, Int, Route.ReplyLoading.ReplyLoadingFrom) -> Unit )
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
app/src/main/java/com/sopt/clody/data/remote/dto/response/DailyDiariesResponseDto.kt(1 hunks)app/src/main/java/com/sopt/clody/data/remote/dto/response/MonthlyCalendarResponseDto.kt(2 hunks)app/src/main/java/com/sopt/clody/domain/model/ReplyStatus.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/ClodyCalendar.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/DailyDiaryListItem.kt(2 hunks)app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/DayItem.kt(2 hunks)app/src/main/java/com/sopt/clody/presentation/ui/home/component/DiaryStateButton.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/home/navigation/HomeNavigation.kt(0 hunks)app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt(10 hunks)app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeViewModel.kt(7 hunks)app/src/main/java/com/sopt/clody/presentation/ui/home/screen/ScrollableCalendar.kt(2 hunks)app/src/main/java/com/sopt/clody/presentation/ui/type/DiaryCloverType.kt(1 hunks)app/src/main/res/drawable/ic_home_draft_saved_clover.xml(1 hunks)app/src/main/res/drawable/ic_home_expired_written_clover.xml(1 hunks)
💤 Files with no reviewable changes (1)
- app/src/main/java/com/sopt/clody/presentation/ui/home/navigation/HomeNavigation.kt
🧰 Additional context used
🧬 Code Graph Analysis (1)
app/src/main/java/com/sopt/clody/presentation/ui/home/component/DiaryStateButton.kt (2)
app/src/main/java/com/sopt/clody/presentation/ui/component/button/ClodyButton.kt (1)
ClodyButton(14-43)app/src/main/java/com/sopt/clody/presentation/ui/component/button/ClodyReplyButton.kt (1)
ClodyReplyButton(14-43)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build
🔇 Additional comments (25)
app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/DayItem.kt (2)
23-23: LGTM: Import added for type-safe enum usage.The import of
ReplyStatussupports the refactoring from string-based to enum-based reply status handling.
60-60: LGTM: Improved type safety with enum comparison.The replacement of string literal comparison with enum comparison (
ReplyStatus.READY_NOT_READ) maintains the same logical behavior while providing better type safety and reducing the risk of typos.app/src/main/java/com/sopt/clody/data/remote/dto/response/DailyDiariesResponseDto.kt (1)
9-9: LGTM: Clean DTO property addition for draft functionality.The
isDraftproperty follows proper serialization patterns and integrates well with the broader draft state management being introduced.app/src/main/java/com/sopt/clody/domain/model/ReplyStatus.kt (2)
7-7: LGTM: Well-named enum values for draft functionality.The addition of
HAS_DRAFTandINVALID_DRAFTenum values clearly supports the new draft state management with descriptive naming.
9-11: LGTM: Useful computed property for common state checks.The
isUnreadOrNotReadproperty encapsulates common business logic for checking unread states, improving code reusability and readability throughout the application.app/src/main/java/com/sopt/clody/data/remote/dto/response/MonthlyCalendarResponseDto.kt (2)
3-3: LGTM: Import added for enum type usage.The import supports the type-safe refactoring from string-based to enum-based reply status.
15-15: Verify backend API compatibility with enum serialization.The change from
StringtoReplyStatusenum improves type safety but requires that the backend API sends values that exactly match the enum names (UNREADY, READY_READ, READY_NOT_READ, HAS_DRAFT, INVALID_DRAFT).Ensure the API contract aligns with these enum values to prevent deserialization failures.
app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/ClodyCalendar.kt (1)
75-75:Details
✅ Verification successful
Verify parameter consistency with DailyDiaryListItem signature.
The parameter change from
state.data.diariestostate.datasuggestsDailyDiaryListItemnow accepts aDailyDiariesResponseDtoobject instead of a list. This refactoring aligns with the draft state handling improvements.Please verify that the
DailyDiaryListItemcomponent signature matches this change:
🏁 Script executed:
#!/bin/bash # Verify DailyDiaryListItem parameter signature ast-grep --pattern 'fun DailyDiaryListItem($$$dailyDiary: DailyDiariesResponseDto$$$)'Length of output: 88
🏁 Script executed:
#!/bin/bash # Locate the DailyDiaryListItem definition to verify its parameter type rg -n 'DailyDiaryListItem' --color neverLength of output: 445
🏁 Script executed:
#!/bin/bash # Show the signature and surrounding lines of DailyDiaryListItem rg -n -A 3 'fun DailyDiaryListItem' app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/DailyDiaryListItem.ktLength of output: 256
Parameter consistency confirmed: DailyDiaryListItem now accepts DailyDiariesResponseDto
The
DailyDiaryListItemsignature in
app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/DailyDiaryListItem.kt
line 33 shows:dailyDiary: DailyDiariesResponseDtowhich matches the change from
state.data.diariestostate.datainClodyCalendar.kt. Refactoring is consistent—no further action needed.app/src/main/res/drawable/ic_home_expired_written_clover.xml (1)
1-10: Well-structured vector drawable for expired written state.The drawable is properly implemented with:
- Consistent dimensions (26x25dp)
- Valid clover shape path data
- Appropriate gray color (#9396A2) for expired state
- Proper XML structure and namespace
app/src/main/res/drawable/ic_home_draft_saved_clover.xml (1)
1-19: Effective visual design for draft saved state.The drawable effectively represents draft state with:
- Consistent dimensions with other clover icons (26x25dp)
- Clear visual hierarchy: light background with dark dots
- Three dots pattern effectively conveys "draft/in-progress" semantics
- Proper XML structure and valid path data
app/src/main/java/com/sopt/clody/presentation/ui/home/screen/ScrollableCalendar.kt (1)
15-15:Details
✅ Verification successful
Excellent type safety improvement using ReplyStatus enum.
The change from
StringtoReplyStatusenum prevents magic string issues and improves type safety. The callback signature and invocation are properly aligned.Please verify that
HomeViewModel.replyStatusis properly exposed asStateFlow<ReplyStatus>:Also applies to: 30-30, 36-39
🏁 Script executed:
#!/bin/bash # Verify HomeViewModel replyStatus property ast-grep --pattern 'val replyStatus: StateFlow<ReplyStatus>'Length of output: 208
HomeViewModel.replyStatus is properly exposed as StateFlow
- Verified in
app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeViewModel.kt:61:val replyStatus: StateFlow<ReplyStatus> get() = _replyStatusThe switch from
(Int, String) -> Unitto(Int, ReplyStatus) -> UnitinScrollableCalendar.ktis consistent and type‐safe. Approving the changes.app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/DailyDiaryListItem.kt (2)
33-33: LGTM! Parameter refactoring improves data access.The change from accepting a list to the complete
DailyDiariesResponseDtoobject enables access to theisDraftproperty, which is essential for the new draft handling logic.
70-108: Well-structured draft state handling logic.The
whenexpression provides clear separation between draft, empty, and normal diary states. The logic correctly prioritizes draft state over empty state, and the UI messages are appropriate for each case.app/src/main/java/com/sopt/clody/presentation/ui/type/DiaryCloverType.kt (2)
27-28: LGTM! New enum values support draft functionality.The addition of
DRAFT_SAVEDandEXPIRED_WRITTENenum values properly extends the clover type system to handle draft states.
32-56: Excellent refactoring for improved readability and logic clarity.The introduction of local variables (
count,reply,hasDiary, etc.) significantly improves code readability. The priority order in thewhenexpression is logical:
- Draft states take highest priority
- Today-specific states
- Other diary states
- Count-based clover types
This ensures draft states are properly handled regardless of other conditions.
app/src/main/java/com/sopt/clody/presentation/ui/home/component/DiaryStateButton.kt (2)
13-15: Excellent parameter refactoring for better declarative design.Replacing
diaryCountandisDeletedwith explicit boolean flags (hasDraft,canWrite,canReply) makes the component's interface more declarative and easier to understand. This eliminates complex conditional logic within the component.
26-62: Clean and logical button state handling.The
whenexpression provides clear priority order:
- Draft continuation ("이어쓰기") - highest priority
- Reply checking ("답장확인")
- Diary writing ("일기쓰기") - enabled
- Diary writing - disabled (fallback)
The logic correctly handles all possible states and the shared modifier reduces code duplication.
app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeViewModel.kt (6)
60-61: Excellent type safety improvement.Converting
_replyStatusfromStringtoReplyStatusenum enhances type safety and prevents invalid state values.
78-80: Appropriate dialog state management.Adding
_showContinueDraftDialogstate properly supports the new draft continuation user flow.
166-169: Comprehensive state reset after diary deletion.The state reset logic correctly resets all related fields (
diaryCount,isDeleted,replyStatus) to their default values, ensuring clean state management.
202-202: Type-safe enum usage.Using the typed
ReplyStatusenum with proper fallback toReplyStatus.UNREADYmaintains type safety throughout the state management.
218-221: Standard setter pattern for dialog state.The
setShowContinueDraftDialogmethod follows the established pattern for state setters in the ViewModel.
227-242: Well-implemented utility methods for business logic.The utility methods correctly encapsulate the business logic:
canWriteDiary(): Properly checks for no existing diary and valid date (today or yesterday)canReplyDiary(): Correctly validates diary exists and isn't deletedisValidDraftDate(): Consistent date validation withcanWriteDiary()These methods improve code maintainability by centralizing business rules and supporting the declarative approach in UI components.
app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt (2)
123-131: Well-implemented draft continuation logicThe branching logic for handling drafts is clean and follows the requirements. Good use of the
ReplyStatusenum and validation checks.
237-268: Excellent implementation of diary deletion flowThe two-step deletion process with clear warnings and proper analytics tracking provides a good user experience while preventing accidental deletions.
| titleMassage = "임시저장된 일기를 이어 쓸까요?", | ||
| descriptionMassage = "답장 기한이 지나서 답장은 받을 수 없어요.", |
There was a problem hiding this comment.
Fix typo in dialog parameter names
The parameter name is misspelled as "Massage" instead of "Message".
-titleMassage = "임시저장된 일기를 이어 쓸까요?",
-descriptionMassage = "답장 기한이 지나서 답장은 받을 수 없어요.",
+titleMessage = "임시저장된 일기를 이어 쓸까요?",
+descriptionMessage = "답장 기한이 지나서 답장은 받을 수 없어요.",-titleMassage = "정말 일기를 삭제할까요?",
-descriptionMassage = "아직 답장이 오지 않았거나 삭제하고\n다시 작성한 일기는 답장을 받을 수 없어요.",
+titleMessage = "정말 일기를 삭제할까요?",
+descriptionMessage = "아직 답장이 오지 않았거나 삭제하고\n다시 작성한 일기는 답장을 받을 수 없어요.",Also applies to: 249-250
🤖 Prompt for AI Agents
In app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt at
lines 220-221 and 249-250, the parameter names "titleMassage" and
"descriptionMassage" are misspelled and should be corrected to "titleMessage"
and "descriptionMessage" respectively. Update these parameter names to fix the
typo in both locations.
| LaunchedEffect(selectedYear, selectedMonth, selectedDay) { | ||
| homeViewModel.refreshCalendarDataCalendarData(selectedYear, selectedMonth) | ||
| LaunchedEffect(selectedDiaryDate.year, selectedDiaryDate.month, selectedDate.dayOfMonth) { | ||
| homeViewModel.refreshCalendarDataCalendarData(selectedDiaryDate.year, selectedDiaryDate.month) |
There was a problem hiding this comment.
Fix typo in method name
The method name has a duplicated suffix.
-homeViewModel.refreshCalendarDataCalendarData(selectedDiaryDate.year, selectedDiaryDate.month)
+homeViewModel.refreshCalendarData(selectedDiaryDate.year, selectedDiaryDate.month)Also applies to: 103-106, 300-300
🤖 Prompt for AI Agents
In app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt at
line 89 and also lines 103-106 and 300, the method name
refreshCalendarDataCalendarData contains a duplicated suffix. Rename the method
calls to refreshCalendarData by removing the extra "CalendarData" suffix to fix
the typo.
| if (isError) { | ||
| FailureScreen( | ||
| message = errorMessage, | ||
| confirmAction = { | ||
| homeViewModel.refreshCalendarDataCalendarData(selectedYear, selectedMonth) | ||
| val selectedDate = homeViewModel.selectedDate.value | ||
| homeViewModel.loadDailyDiariesData(selectedYear, selectedMonth, selectedDate.dayOfMonth) | ||
| }, | ||
| ) | ||
| } else { |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Remove duplicate error handling
This error handling block is redundant since HomeRoute already handles the error state at lines 99-114 and doesn't call HomeScreen when isError is true.
- if (isError) {
- FailureScreen(
- message = errorMessage,
- confirmAction = {
- homeViewModel.refreshCalendarDataCalendarData(selectedYear, selectedMonth)
- homeViewModel.loadDailyDiariesData(selectedYear, selectedMonth, selectedDate.dayOfMonth)
- },
- )
- } else {Also remove the closing brace at line 418:
- }📝 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.
| if (isError) { | |
| FailureScreen( | |
| message = errorMessage, | |
| confirmAction = { | |
| homeViewModel.refreshCalendarDataCalendarData(selectedYear, selectedMonth) | |
| val selectedDate = homeViewModel.selectedDate.value | |
| homeViewModel.loadDailyDiariesData(selectedYear, selectedMonth, selectedDate.dayOfMonth) | |
| }, | |
| ) | |
| } else { | |
| // (Lines 296–304 removed – the duplicate `if (isError) { … } else {` block has been deleted, | |
| // since HomeRoute already handles error states.) | |
| // (Also remove the corresponding closing brace at line 418.) | |
| // The rest of HomeScreen's UI content now follows here unconditionally. |
🤖 Prompt for AI Agents
In app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt
between lines 296 and 304, remove the entire if (isError) block that shows
FailureScreen, as error handling is already done in HomeRoute at lines 99-114
and HomeScreen is not called when isError is true. Also, remove the extra
closing brace at line 418 to fix the syntax.
📌 ISSUE
closed #270
📄 Work Description
✨ PR Point
구현하면서 나중에 홈 화면 개편하기 쉽게 기존 홈 부분 코드로 약간 리펙토링 했습니다.
다 한거같긴 한데 잘 모르겠음...
📸 ScreenShot/Video
Summary by CodeRabbit
New Features
Improvements