Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions app/src/main/java/com/egobook/app/data/api/DiaryApiService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package com.egobook.app.data.api

import com.egobook.app.data.model.ApiResponse
import com.egobook.app.data.model.diary.request.DiaryCreateRequest
import com.egobook.app.data.model.diary.request.DiaryExportRequest
import com.egobook.app.data.model.diary.request.DiaryUpdateRequest
import com.egobook.app.data.model.diary.response.DiariesResponse
import com.egobook.app.data.model.diary.response.DiaryCreateResponse
import com.egobook.app.data.model.diary.response.DiaryDeleteResponse
import com.egobook.app.data.model.diary.response.DiaryEntryResponse
import com.egobook.app.data.model.diary.response.DiaryExportResponse
import com.google.android.gms.common.api.Api
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
Expand Down Expand Up @@ -51,4 +54,10 @@ interface DiaryApiService {
@Body request: DiaryUpdateRequest
): ApiResponse<DiaryEntryResponse>

//일기 내보내기
@POST("/diaries/export")
suspend fun exportDiary(
@Body request: DiaryExportRequest
): ApiResponse<DiaryExportResponse>

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@ import kotlinx.serialization.Serializable
data class DiaryExportRequest (
@SerialName("format")
val format: String,
@SerialName("startDate")
val startDate: String,
@SerialName("endDate")
val endDate: String,

)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.egobook.app.data.model.diary.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class DiaryExportResponse(
@SerialName("fileUrl")
val fileUrl: String,
)
75 changes: 57 additions & 18 deletions app/src/main/java/com/egobook/app/ui/diary/view/CalenderFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.children
import androidx.core.view.isInvisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
Expand All @@ -35,6 +36,7 @@ import java.time.YearMonth
import java.time.format.TextStyle
import java.util.Locale
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
import timber.log.Timber

Expand Down Expand Up @@ -63,10 +65,22 @@ class CalenderFragment : Fragment() {
v.setPadding(v.paddingLeft, v.paddingTop, v.paddingRight, systemBars.bottom)
insets
}


// 1. 먼저 초기 년월 결정 (인자 있으면 그걸로, 없으면 현재 달)
val initialMonth = getInitialMonthFromArgs()

// 2. 캘린더를 처음에는 숨김 (깜빡임 방지)
binding.calendarView.visibility = View.INVISIBLE
binding.calendarHeaderLayout.visibility = View.INVISIBLE

setupDayOfWeekTitles()
setupCalendar()
observeViewModel()
setupCalendar(initialMonth) // 초기 년월 전달

// 3. ViewModel을 초기 년월로 설정 (데이터 로드)
viewModel.setYearMonth(initialMonth)

// 4. observing 시작
observeViewModel(initialMonth) // 초기 년월 전달해서 첫 emission 검증
setupMonthDialogResultListener()

binding.apply {
Expand Down Expand Up @@ -102,7 +116,22 @@ class CalenderFragment : Fragment() {
}
}
}


/**
* 초기 년월을 인자에서 추출 (없으면 현재 달 반환)
*/
private fun getInitialMonthFromArgs(): YearMonth {
val args = arguments
val year = args?.getInt("year", -1) ?: -1
val month = args?.getInt("month", -1) ?: -1

return if (year != -1 && month != -1) {
YearMonth.of(year, month)
} else {
YearMonth.now()
}
}

/**
* MonthDialogFragment에서 월 선택 결과 수신
*/
Expand All @@ -121,17 +150,30 @@ class CalenderFragment : Fragment() {
/**
* ViewModel 상태 관찰 - 스와이프 없이 해당 월 즉시 표시
*/
private fun observeViewModel() {
private fun observeViewModel(expectedInitialMonth: YearMonth) {
viewLifecycleOwner.lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
var isCorrectMonthReceived = false
viewModel.state.collectLatest { state ->
// 예상한 초기 달이 나올 때까지 대기 (깜빡임 방지)
if (!isCorrectMonthReceived && state.selectedYearMonth != expectedInitialMonth) {
return@collectLatest // 잘못된 달은 무시
}
isCorrectMonthReceived = true

// 애니메이션 없이 해당 월 즉시 이동
binding.calendarView.scrollToMonth(state.selectedYearMonth)
// 상단 텍스트 업데이트
binding.tvYear.text = state.selectedYearMonth.year.toString()
binding.tvMonth.text = "${state.selectedYearMonth.monthValue}월"
// 중요: 감정 데이터 변경 시 해당 월만 캘린더 뷰 갱신
binding.calendarView.notifyMonthChanged(state.selectedYearMonth)

// 첫 번째 올바른 상태 업데이트 후 캘린더 표시
if (binding.calendarView.isInvisible) {
binding.calendarView.visibility = View.VISIBLE
binding.calendarHeaderLayout.visibility = View.VISIBLE
}
}
}
}
Expand Down Expand Up @@ -178,33 +220,30 @@ class CalenderFragment : Fragment() {
/**
* 달력 설정 및 초기화
*/
private fun setupCalendar() {
val currentMonth = YearMonth.now()

initializeCalendarRange(currentMonth)
initializeYearMonthText(currentMonth)
private fun setupCalendar(initialMonth: YearMonth) {
initializeCalendarRange(initialMonth)
initializeYearMonthText(initialMonth)
setupDayBinder()
// 초기 로드는 ViewModel의 init 블록에서 처리
}

/**
* 달력 범위 설정 (과거 100개월 ~ 미래 100개월)
*/
private fun initializeCalendarRange(currentMonth: YearMonth) {
val startMonth = currentMonth.minusMonths(100)
val endMonth = currentMonth.plusMonths(100)
private fun initializeCalendarRange(initialMonth: YearMonth) {
val startMonth = initialMonth.minusMonths(100)
val endMonth = initialMonth.plusMonths(100)
val firstDayOfWeek = DayOfWeek.MONDAY

binding.calendarView.setup(startMonth, endMonth, firstDayOfWeek)
binding.calendarView.scrollToMonth(currentMonth)
binding.calendarView.scrollToMonth(initialMonth)
}

/**
* 초기 연/월 텍스트 설정
*/
private fun initializeYearMonthText(currentMonth: YearMonth) {
binding.tvYear.text = currentMonth.year.toString()
binding.tvMonth.text = "${currentMonth.monthValue}월"
private fun initializeYearMonthText(initialMonth: YearMonth) {
binding.tvYear.text = initialMonth.year.toString()
binding.tvMonth.text = "${initialMonth.monthValue}월"
}

/**
Expand Down
11 changes: 10 additions & 1 deletion app/src/main/java/com/egobook/app/ui/diary/view/DiaryFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,17 @@ import kotlin.getValue
}
}
btnCalender.setOnClickListener {
findNavController().navigate(R.id.action_diaryFragment_to_calenderFragment)
val date = viewModel.state.value.selectedDate

val action = DiaryFragmentDirections
.actionDiaryFragmentToCalenderFragment(
year = date.year,
month = date.monthValue
)

findNavController().navigate(action)
}

btnExport.setOnClickListener {
applyScreenBlur(BlurLevel.BASE)
val dialog = DiaryExportDialogFragment()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,17 @@ class CalenderViewModel @Inject constructor(
get() = _state.value.selectedYearMonth

/**
* 초기 로드
* 초기 로드 - 외부에서 명시적으로 호출 필요
*/
init {
Log.d("ViewModel1", "=== ViewModel INIT === selectedYearMonth=${_state.value.selectedYearMonth}")
// init에서 자동 로드하지 않음 - Fragment에서 초기 년월 설정 후 명시적 호출
}

/**
* 초기 캘린더 데이터 로드 (Fragment에서 명시적 호출)
*/
fun initializeCalendar() {
loadCalender(_state.value.selectedYearMonth)
}

Expand Down
7 changes: 5 additions & 2 deletions app/src/main/res/layout/fragment_calender.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:visibility="invisible"
app:layout_constraintTop_toBottomOf="@id/top_btn_layout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
Expand All @@ -58,7 +59,8 @@
android:id="@+id/tv_year"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2025"
android:text=""
tools:text="2025"
android:textColor="@color/cos_black"
android:fontFamily="@font/arita_medium"
android:textSize="14sp" />
Expand Down Expand Up @@ -86,7 +88,8 @@
android:id="@+id/tv_month"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="12월"
android:text=""
tools:text="12월"
android:textSize="24sp"
android:layout_marginHorizontal="24dp"
android:fontFamily="@font/arita_semibold" />
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/res/navigation/bottom_navigation.xml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,16 @@
android:id="@+id/calenderFragment"
android:name="com.egobook.app.ui.diary.view.CalenderFragment"
android:label="달력 화면" >

<argument
android:name="year"
app:argType="integer"
android:defaultValue="-1"/>

<argument
android:name="month"
app:argType="integer"
android:defaultValue="-1"/>

<!-- DiaryFragment로 돌아가는 액션 (날짜 인자 전달) -->
<action
Expand Down