From 24bc3e226639fe27f8b434f18fa2e80cc7573c69 Mon Sep 17 00:00:00 2001 From: boiledegg Date: Wed, 10 Jul 2024 02:28:15 +0900 Subject: [PATCH 01/14] =?UTF-8?q?[MOD/#20]=20selectedDate=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../terning/feature/calendar/CalendarMonth.kt | 2 +- .../feature/calendar/CalendarMonths.kt | 7 ++-- .../terning/feature/calendar/CalendarRoute.kt | 33 +++++++++++-------- .../feature/calendar/CalendarViewModel.kt | 3 +- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarMonth.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarMonth.kt index e9d41dcf0..733f4a36e 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarMonth.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarMonth.kt @@ -25,7 +25,7 @@ fun CalendarMonth( modifier: Modifier = Modifier, monthData: MonthData, onDateSelected: (LocalDate) -> Unit, - selectedDate: LocalDate, + selectedDate: LocalDate?, scrapLists: List> = listOf() ) { Column( diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarMonths.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarMonths.kt index 4f179af8d..25eb94ca0 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarMonths.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarMonths.kt @@ -1,7 +1,6 @@ package com.terning.feature.calendar import androidx.compose.foundation.background -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.LazyRow import androidx.compose.runtime.Composable @@ -16,12 +15,12 @@ import java.time.YearMonth @Composable fun CalendarMonths( - modifier: Modifier = Modifier, listState: LazyListState, onDateSelected: (LocalDate) -> Unit, pages: Int, - selectedDate: LocalDate, - scrapLists: List> + selectedDate: LocalDate?, + scrapLists: List>, + modifier: Modifier = Modifier, ) { LazyRow( modifier = modifier diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt index c706c5715..68f5e852c 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt @@ -29,6 +29,7 @@ import com.terning.feature.calendar.component.WeekDaysHeader import com.terning.feature.calendar.models.CalendarState import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.launch +import java.time.LocalDate @Composable fun CalendarRoute() { @@ -41,14 +42,14 @@ fun CalendarScreen( viewModel: CalendarViewModel = hiltViewModel() ) { val selectedDate by viewModel.selectedDate.collectAsState() - val state by remember{ mutableStateOf(CalendarState()) } + val state by remember { mutableStateOf(CalendarState()) } val listState = rememberLazyListState( initialFirstVisibleItemIndex = state.getInitialPage() ) - var currentDate by remember { mutableStateOf(selectedDate) } - var currentPage by remember { mutableIntStateOf(listState.firstVisibleItemIndex)} + var currentDate by remember { mutableStateOf(LocalDate.now()) } + var currentPage by remember { mutableIntStateOf(listState.firstVisibleItemIndex) } var isListExpanded by remember { mutableStateOf(false) } var isWeekEnabled by remember { mutableStateOf(false) } @@ -56,19 +57,22 @@ fun CalendarScreen( LaunchedEffect(key1 = listState) { snapshotFlow { listState.firstVisibleItemIndex } .distinctUntilChanged() - .collect{ - val swipeDirection = (listState.firstVisibleItemIndex - currentPage).coerceIn(-1, 1).toLong() + .collect { + val swipeDirection = + (listState.firstVisibleItemIndex - currentPage).coerceIn(-1, 1).toLong() currentDate = currentDate.plusMonths(swipeDirection) currentPage = listState.firstVisibleItemIndex } } LaunchedEffect(key1 = selectedDate) { - isWeekEnabled = true + if (selectedDate != null) + isWeekEnabled = true } BackHandler { - isWeekEnabled = false + if (isWeekEnabled) + isWeekEnabled = false } Scaffold( @@ -91,15 +95,17 @@ fun CalendarScreen( ) { paddingValues -> Column( modifier = Modifier - .fillMaxWidth() + .fillMaxSize() .padding(top = paddingValues.calculateTopPadding()) ) { WeekDaysHeader() - Spacer(modifier = Modifier - .fillMaxWidth() - .height(1.dp) - .background(color = Grey200) + Spacer( + modifier = Modifier + .fillMaxWidth() + .height(1.dp) + .background(color = Grey200) ) + CalendarMonths( modifier = Modifier.fillMaxSize(), selectedDate = selectedDate, @@ -108,9 +114,8 @@ fun CalendarScreen( }, listState = listState, pages = state.getPageCount(), - scrapLists = viewModel.mockScrapList + scrapLists = viewModel.mockScrapList, ) } - } } diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarViewModel.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarViewModel.kt index d57863782..9c7568706 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarViewModel.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarViewModel.kt @@ -13,7 +13,6 @@ import com.terning.feature.calendar.models.Scrap import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import java.time.LocalDate import javax.inject.Inject @@ -21,7 +20,7 @@ import javax.inject.Inject @HiltViewModel class CalendarViewModel @Inject constructor( ) : ViewModel() { - private val _selectedDate = MutableStateFlow(LocalDate.now()) + private val _selectedDate = MutableStateFlow(null) val selectedDate get() = _selectedDate.asStateFlow() fun updateSelectedDate(date: LocalDate) = viewModelScope.launch { From da62b7dce3b49e0e32771edab3ef23ec6746275d Mon Sep 17 00:00:00 2001 From: boiledegg Date: Wed, 10 Jul 2024 02:29:04 +0900 Subject: [PATCH 02/14] =?UTF-8?q?[UI/#20]=20=EC=A3=BC=EA=B0=84=20=EC=BA=98?= =?UTF-8?q?=EB=A6=B0=EB=8D=94=20UI=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../terning/feature/calendar/CalendarWeek.kt | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 feature/src/main/java/com/terning/feature/calendar/CalendarWeek.kt diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarWeek.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarWeek.kt new file mode 100644 index 000000000..5dc27f542 --- /dev/null +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarWeek.kt @@ -0,0 +1,50 @@ +package com.terning.feature.calendar + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.pager.HorizontalPager +import androidx.compose.foundation.pager.rememberPagerState +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.terning.feature.calendar.models.MonthData +import java.time.LocalDate +import java.time.YearMonth + +@Composable +fun CalendarWeek( + modifier: Modifier = Modifier, + selectedDate: LocalDate, + onDateSelected: (LocalDate) -> Unit = {} +) { + val monthData = MonthData(YearMonth.of(selectedDate.year, selectedDate.monthValue)) + val currentWeek = selectedDate.dayOfMonth / 7 + + val pagerState = rememberPagerState ( + initialPage = currentWeek, + pageCount = {monthData.totalDays / 7} + ) + + HorizontalPager( + modifier = modifier, + state = pagerState) { page -> + LazyRow( + modifier = Modifier + .fillMaxWidth() + .padding(20.dp), + horizontalArrangement = Arrangement.SpaceBetween + ) { + items(items = monthData.calendarMonth.weekDays[page]) { day -> + CalendarDay( + dayData = day, + isSelected = selectedDate == day.date, + isToday = day.date == LocalDate.now(), + onDateSelected = onDateSelected + ) + } + } + } +} \ No newline at end of file From 9c70c38475d8ad852bc353486df140edfcfc1ab4 Mon Sep 17 00:00:00 2001 From: boiledegg Date: Wed, 10 Jul 2024 02:29:38 +0900 Subject: [PATCH 03/14] =?UTF-8?q?[UI/#20]=20=EC=A3=BC=EA=B0=84=20=EC=BA=98?= =?UTF-8?q?=EB=A6=B0=EB=8D=94=20+=20=EB=8B=B9=EC=9D=BC=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=9E=A9=20=EB=AA=A9=EB=A1=9D=20=ED=91=9C=EC=8B=9C=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/calendar/CalendarWeekWithScrap.kt | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 feature/src/main/java/com/terning/feature/calendar/CalendarWeekWithScrap.kt diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarWeekWithScrap.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarWeekWithScrap.kt new file mode 100644 index 000000000..e8c28d5f2 --- /dev/null +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarWeekWithScrap.kt @@ -0,0 +1,59 @@ +package com.terning.feature.calendar + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Card +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.shadow +import androidx.compose.ui.unit.dp +import com.terning.core.designsystem.theme.Grey200 +import com.terning.core.designsystem.theme.White +import com.terning.feature.calendar.models.Scrap +import java.time.LocalDate + +@Composable +fun CalendarWeekWithScrap( + modifier: Modifier = Modifier, + selectedDate: LocalDate?, + scrapLists: List> = listOf(), + onDateSelected: (LocalDate) -> Unit +) { + Column( + modifier = modifier + ) { + Card( + modifier = Modifier + .border(0.dp, Grey200, RoundedCornerShape(bottomStart = 20.dp, bottomEnd = 20.dp)) + .shadow( + shape = RoundedCornerShape(bottomStart = 20.dp, bottomEnd = 20.dp), + elevation = 1.dp + ), + + shape = RoundedCornerShape(bottomStart = 20.dp, bottomEnd = 20.dp), + ) { + CalendarWeek( + modifier = Modifier + .fillMaxWidth() + .background(White), + selectedDate = selectedDate?: LocalDate.now(), + onDateSelected = onDateSelected + ) + } + + LazyColumn( + modifier = Modifier + .fillMaxWidth() + ){ + /*items(items = scrapLists[selectedDate?.dayOfMonth - 1]) { + + }*/ + + } + } + +} \ No newline at end of file From ab47b7b3c7c42d0d173dfed76948cafcdc6f6115 Mon Sep 17 00:00:00 2001 From: boiledegg Date: Wed, 10 Jul 2024 02:30:22 +0900 Subject: [PATCH 04/14] =?UTF-8?q?[FEAT/#20]=20=EC=BA=98=EB=A6=B0=EB=8D=94?= =?UTF-8?q?=20=EC=A0=84=ED=99=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../terning/feature/calendar/CalendarRoute.kt | 51 +++++++++++++++---- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt index 68f5e852c..a62f6a8d9 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt @@ -1,6 +1,11 @@ package com.terning.feature.calendar import androidx.activity.compose.BackHandler +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.SizeTransform +import androidx.compose.animation.slideInVertically +import androidx.compose.animation.slideOutVertically +import androidx.compose.animation.togetherWith import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -106,16 +111,44 @@ fun CalendarScreen( .background(color = Grey200) ) - CalendarMonths( - modifier = Modifier.fillMaxSize(), - selectedDate = selectedDate, - onDateSelected = { - viewModel.updateSelectedDate(it) + AnimatedContent( + targetState = isWeekEnabled, + transitionSpec = { + if (!targetState) { + slideInVertically { fullHeight -> -fullHeight } togetherWith + slideOutVertically { fullHeight -> fullHeight } + } else { + slideInVertically { fullHeight -> fullHeight } togetherWith + slideOutVertically { fullHeight -> -fullHeight } + }.using( + sizeTransform = SizeTransform(clip = true) + ) }, - listState = listState, - pages = state.getPageCount(), - scrapLists = viewModel.mockScrapList, - ) + label = "" + ) { targetState -> + if (!targetState) { + CalendarMonths( + modifier = Modifier.fillMaxSize(), + selectedDate = selectedDate, + onDateSelected = { + viewModel.updateSelectedDate(it) + }, + listState = listState, + pages = state.getPageCount(), + scrapLists = viewModel.mockScrapList, + ) + } else { + CalendarWeekWithScrap( + modifier = Modifier + .fillMaxSize(), + selectedDate = selectedDate ?: LocalDate.now(), + scrapLists = viewModel.mockScrapList, + onDateSelected = { + viewModel.updateSelectedDate(it) + } + ) + } + } } } } From b0cc77f7d0d56ee7a1820444d5c955a821c0887c Mon Sep 17 00:00:00 2001 From: boiledegg Date: Wed, 10 Jul 2024 02:52:34 +0900 Subject: [PATCH 05/14] =?UTF-8?q?[CHORE/#20]=20=EC=95=A0=EB=8B=88=EB=A9=94?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EB=9D=BC=EB=B2=A8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/terning/feature/calendar/CalendarRoute.kt | 6 +++++- feature/src/main/res/values/strings.xml | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt index a62f6a8d9..e187f8e6a 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt @@ -26,9 +26,11 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import com.terning.core.designsystem.theme.Grey200 +import com.terning.feature.R import com.terning.feature.calendar.component.CalendarTopBar import com.terning.feature.calendar.component.WeekDaysHeader import com.terning.feature.calendar.models.CalendarState @@ -124,7 +126,7 @@ fun CalendarScreen( sizeTransform = SizeTransform(clip = true) ) }, - label = "" + label = stringResource(id = R.string.calendar_animation_label) ) { targetState -> if (!targetState) { CalendarMonths( @@ -152,3 +154,5 @@ fun CalendarScreen( } } } + + diff --git a/feature/src/main/res/values/strings.xml b/feature/src/main/res/values/strings.xml index 2247cdd3a..73a86c796 100644 --- a/feature/src/main/res/values/strings.xml +++ b/feature/src/main/res/values/strings.xml @@ -35,5 +35,6 @@ previous next list + Calendar Transition \ No newline at end of file From cdd13f8b66286787a8b4b10b4ed38102443a32b5 Mon Sep 17 00:00:00 2001 From: boiledegg Date: Wed, 10 Jul 2024 03:57:06 +0900 Subject: [PATCH 06/14] =?UTF-8?q?[MOD/#20]=20LocalDate=20=ED=99=95?= =?UTF-8?q?=EC=9E=A5=ED=95=A8=EC=88=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/terning/core/extension/LocalDateExt.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/terning/core/extension/LocalDateExt.kt b/core/src/main/java/com/terning/core/extension/LocalDateExt.kt index edcf61c96..ee8c97476 100644 --- a/core/src/main/java/com/terning/core/extension/LocalDateExt.kt +++ b/core/src/main/java/com/terning/core/extension/LocalDateExt.kt @@ -3,4 +3,8 @@ package com.terning.core.extension import java.time.LocalDate fun LocalDate.getStringAsTitle(): String = - "${year}년 ${monthValue.toString().padStart(2, '0')}월" \ No newline at end of file + "${year}년 ${monthValue.toString().padStart(2, '0')}월" + +fun LocalDate.getWeekIndexContainingSelectedDate(): Int = dayOfMonth / 7 + +fun LocalDate.isToday(): Boolean = this == LocalDate.now() \ No newline at end of file From 21a8942c4f6b07123c13b94cfe5df7c3789fbd2c Mon Sep 17 00:00:00 2001 From: boiledegg Date: Wed, 10 Jul 2024 03:57:48 +0900 Subject: [PATCH 07/14] =?UTF-8?q?[MOD/#20]=20=ED=99=95=EC=9E=A5=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EA=B8=B0=EB=B0=98=20=EC=BD=94=EB=93=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/terning/feature/calendar/CalendarMonth.kt | 4 ++-- .../main/java/com/terning/feature/calendar/CalendarWeek.kt | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarMonth.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarMonth.kt index 3bbc82493..48cab63ce 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarMonth.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarMonth.kt @@ -15,7 +15,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.terning.core.designsystem.theme.Grey150 import com.terning.core.designsystem.theme.TerningPointTheme -import com.terning.core.designsystem.theme.TerningTheme +import com.terning.core.extension.isToday import com.terning.feature.calendar.models.MonthData import com.terning.feature.calendar.models.Scrap import java.time.LocalDate @@ -49,7 +49,7 @@ fun CalendarMonth( CalendarDay( dayData = day, isSelected = selectedDate == day.date, - isToday = day.date == LocalDate.now(), + isToday = day.date.isToday(), onDateSelected = onDateSelected ) if(!day.isOutDate) { diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarWeek.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarWeek.kt index 5dc27f542..20c4d993d 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarWeek.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarWeek.kt @@ -10,6 +10,8 @@ import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import com.terning.core.extension.getWeekIndexContainingSelectedDate +import com.terning.core.extension.isToday import com.terning.feature.calendar.models.MonthData import java.time.LocalDate import java.time.YearMonth @@ -21,7 +23,7 @@ fun CalendarWeek( onDateSelected: (LocalDate) -> Unit = {} ) { val monthData = MonthData(YearMonth.of(selectedDate.year, selectedDate.monthValue)) - val currentWeek = selectedDate.dayOfMonth / 7 + val currentWeek = selectedDate.getWeekIndexContainingSelectedDate() val pagerState = rememberPagerState ( initialPage = currentWeek, @@ -41,7 +43,7 @@ fun CalendarWeek( CalendarDay( dayData = day, isSelected = selectedDate == day.date, - isToday = day.date == LocalDate.now(), + isToday = day.date.isToday(), onDateSelected = onDateSelected ) } From 76615ccf5615a4e136c7e23aaed20ceeeec3f8c8 Mon Sep 17 00:00:00 2001 From: boiledegg Date: Wed, 10 Jul 2024 04:17:06 +0900 Subject: [PATCH 08/14] =?UTF-8?q?[FEAT/#20]=20=EC=A3=BC=EA=B0=84->?= =?UTF-8?q?=EC=9B=94=EA=B0=84=20=EC=A0=84=ED=99=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/terning/feature/calendar/CalendarRoute.kt | 8 ++++---- .../com/terning/feature/calendar/CalendarViewModel.kt | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt index e187f8e6a..3acf797fe 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt @@ -73,13 +73,13 @@ fun CalendarScreen( } LaunchedEffect(key1 = selectedDate) { - if (selectedDate != null) - isWeekEnabled = true + isWeekEnabled = selectedDate != null } BackHandler { - if (isWeekEnabled) - isWeekEnabled = false + if (isWeekEnabled) { + viewModel.updateSelectedDate(selectedDate?: LocalDate.now()) + } } Scaffold( diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarViewModel.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarViewModel.kt index 9c7568706..9eda16612 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarViewModel.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarViewModel.kt @@ -26,6 +26,9 @@ class CalendarViewModel @Inject constructor( fun updateSelectedDate(date: LocalDate) = viewModelScope.launch { if (_selectedDate.value != date) { _selectedDate.value = date + } else { + _selectedDate.value = null + } } From 6e89f2a0f30ba9bd11b23632c86c0926eca3203a Mon Sep 17 00:00:00 2001 From: boiledegg Date: Wed, 10 Jul 2024 05:57:05 +0900 Subject: [PATCH 09/14] =?UTF-8?q?[ADD/#20]=20SelectedDateState=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../terning/feature/calendar/models/SelectedDateState.kt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 feature/src/main/java/com/terning/feature/calendar/models/SelectedDateState.kt diff --git a/feature/src/main/java/com/terning/feature/calendar/models/SelectedDateState.kt b/feature/src/main/java/com/terning/feature/calendar/models/SelectedDateState.kt new file mode 100644 index 000000000..04864c848 --- /dev/null +++ b/feature/src/main/java/com/terning/feature/calendar/models/SelectedDateState.kt @@ -0,0 +1,8 @@ +package com.terning.feature.calendar.models + +import java.time.LocalDate + +data class SelectedDateState( + val selectedDate: LocalDate, + val isEnabled: Boolean +) From 05f7daf15955626cb29cf8254ccf89d04ed057cf Mon Sep 17 00:00:00 2001 From: boiledegg Date: Wed, 10 Jul 2024 05:57:26 +0900 Subject: [PATCH 10/14] =?UTF-8?q?[REFACTOR/#20]=20SelectedDateState=20?= =?UTF-8?q?=EA=B8=B0=EB=B0=98=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../terning/feature/calendar/CalendarMonth.kt | 7 +++-- .../feature/calendar/CalendarMonths.kt | 3 +- .../terning/feature/calendar/CalendarRoute.kt | 13 +++------ .../feature/calendar/CalendarViewModel.kt | 29 +++++++++++++++---- .../terning/feature/calendar/CalendarWeek.kt | 10 ++++--- .../feature/calendar/CalendarWeekWithScrap.kt | 5 ++-- 6 files changed, 43 insertions(+), 24 deletions(-) diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarMonth.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarMonth.kt index 48cab63ce..fc9636da3 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarMonth.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarMonth.kt @@ -18,6 +18,7 @@ import com.terning.core.designsystem.theme.TerningPointTheme import com.terning.core.extension.isToday import com.terning.feature.calendar.models.MonthData import com.terning.feature.calendar.models.Scrap +import com.terning.feature.calendar.models.SelectedDateState import java.time.LocalDate import java.time.YearMonth @@ -26,7 +27,7 @@ fun CalendarMonth( modifier: Modifier = Modifier, monthData: MonthData, onDateSelected: (LocalDate) -> Unit, - selectedDate: LocalDate?, + selectedDate: SelectedDateState, scrapLists: List> = listOf() ) { Column( @@ -48,7 +49,7 @@ fun CalendarMonth( ) { CalendarDay( dayData = day, - isSelected = selectedDate == day.date, + isSelected = selectedDate.selectedDate == day.date && selectedDate.isEnabled, isToday = day.date.isToday(), onDateSelected = onDateSelected ) @@ -79,7 +80,7 @@ fun CalendarMonthPreview() { TerningPointTheme { CalendarMonth( monthData = MonthData(YearMonth.now()), - selectedDate = LocalDate.now(), + selectedDate = SelectedDateState(LocalDate.now(), true), onDateSelected = {}, scrapLists = listOf() ) diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarMonths.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarMonths.kt index 25eb94ca0..5d4ecc101 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarMonths.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarMonths.kt @@ -10,6 +10,7 @@ import com.terning.feature.calendar.models.CalendarDefaults.flingBehavior import com.terning.feature.calendar.models.CalendarState.Companion.getDateByPage import com.terning.feature.calendar.models.MonthData import com.terning.feature.calendar.models.Scrap +import com.terning.feature.calendar.models.SelectedDateState import java.time.LocalDate import java.time.YearMonth @@ -18,7 +19,7 @@ fun CalendarMonths( listState: LazyListState, onDateSelected: (LocalDate) -> Unit, pages: Int, - selectedDate: LocalDate?, + selectedDate: SelectedDateState, scrapLists: List>, modifier: Modifier = Modifier, ) { diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt index 3acf797fe..03afb65e3 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt @@ -59,7 +59,6 @@ fun CalendarScreen( var currentPage by remember { mutableIntStateOf(listState.firstVisibleItemIndex) } var isListExpanded by remember { mutableStateOf(false) } - var isWeekEnabled by remember { mutableStateOf(false) } LaunchedEffect(key1 = listState) { snapshotFlow { listState.firstVisibleItemIndex } @@ -72,13 +71,9 @@ fun CalendarScreen( } } - LaunchedEffect(key1 = selectedDate) { - isWeekEnabled = selectedDate != null - } - BackHandler { - if (isWeekEnabled) { - viewModel.updateSelectedDate(selectedDate?: LocalDate.now()) + if (selectedDate.isEnabled) { + viewModel.updateSelectedDate(selectedDate.selectedDate) } } @@ -114,7 +109,7 @@ fun CalendarScreen( ) AnimatedContent( - targetState = isWeekEnabled, + targetState = selectedDate.isEnabled, transitionSpec = { if (!targetState) { slideInVertically { fullHeight -> -fullHeight } togetherWith @@ -143,7 +138,7 @@ fun CalendarScreen( CalendarWeekWithScrap( modifier = Modifier .fillMaxSize(), - selectedDate = selectedDate ?: LocalDate.now(), + selectedDate = selectedDate, scrapLists = viewModel.mockScrapList, onDateSelected = { viewModel.updateSelectedDate(it) diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarViewModel.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarViewModel.kt index 9eda16612..6a286807b 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarViewModel.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarViewModel.kt @@ -10,9 +10,11 @@ import com.terning.core.designsystem.theme.CalPurple import com.terning.core.designsystem.theme.CalRed import com.terning.core.designsystem.theme.CalYellow import com.terning.feature.calendar.models.Scrap +import com.terning.feature.calendar.models.SelectedDateState import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import java.time.LocalDate import javax.inject.Inject @@ -20,15 +22,29 @@ import javax.inject.Inject @HiltViewModel class CalendarViewModel @Inject constructor( ) : ViewModel() { - private val _selectedDate = MutableStateFlow(null) + private val _selectedDate = MutableStateFlow( + SelectedDateState( + selectedDate = LocalDate.now(), + isEnabled = false + ) + ) val selectedDate get() = _selectedDate.asStateFlow() fun updateSelectedDate(date: LocalDate) = viewModelScope.launch { - if (_selectedDate.value != date) { - _selectedDate.value = date + if (_selectedDate.value.selectedDate != date) { + _selectedDate.update { currentState -> + currentState.copy( + selectedDate = date, + isEnabled = true + ) + } } else { - _selectedDate.value = null - + _selectedDate.update { currentState -> + currentState.copy( + selectedDate = date, + isEnabled = !_selectedDate.value.isEnabled + ) + } } } @@ -63,18 +79,21 @@ class CalendarViewModel @Inject constructor( ) ) } + 3 -> { list.add( i, listOf() ) } + 4 -> { list.add( i, listOf() ) } + 5 -> { list.add( i, diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarWeek.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarWeek.kt index 20c4d993d..7fb0e5d43 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarWeek.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarWeek.kt @@ -13,17 +13,19 @@ import androidx.compose.ui.unit.dp import com.terning.core.extension.getWeekIndexContainingSelectedDate import com.terning.core.extension.isToday import com.terning.feature.calendar.models.MonthData +import com.terning.feature.calendar.models.SelectedDateState import java.time.LocalDate import java.time.YearMonth @Composable fun CalendarWeek( modifier: Modifier = Modifier, - selectedDate: LocalDate, + selectedDate: SelectedDateState, onDateSelected: (LocalDate) -> Unit = {} ) { - val monthData = MonthData(YearMonth.of(selectedDate.year, selectedDate.monthValue)) - val currentWeek = selectedDate.getWeekIndexContainingSelectedDate() + val date = selectedDate.selectedDate + val monthData = MonthData(YearMonth.of(date.year, date.monthValue)) + val currentWeek = date.getWeekIndexContainingSelectedDate() val pagerState = rememberPagerState ( initialPage = currentWeek, @@ -42,7 +44,7 @@ fun CalendarWeek( items(items = monthData.calendarMonth.weekDays[page]) { day -> CalendarDay( dayData = day, - isSelected = selectedDate == day.date, + isSelected = selectedDate.selectedDate == day.date && selectedDate.isEnabled, isToday = day.date.isToday(), onDateSelected = onDateSelected ) diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarWeekWithScrap.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarWeekWithScrap.kt index e8c28d5f2..00a1adde4 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarWeekWithScrap.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarWeekWithScrap.kt @@ -14,12 +14,13 @@ import androidx.compose.ui.unit.dp import com.terning.core.designsystem.theme.Grey200 import com.terning.core.designsystem.theme.White import com.terning.feature.calendar.models.Scrap +import com.terning.feature.calendar.models.SelectedDateState import java.time.LocalDate @Composable fun CalendarWeekWithScrap( modifier: Modifier = Modifier, - selectedDate: LocalDate?, + selectedDate: SelectedDateState, scrapLists: List> = listOf(), onDateSelected: (LocalDate) -> Unit ) { @@ -40,7 +41,7 @@ fun CalendarWeekWithScrap( modifier = Modifier .fillMaxWidth() .background(White), - selectedDate = selectedDate?: LocalDate.now(), + selectedDate = selectedDate, onDateSelected = onDateSelected ) } From 43482a49236e559b71c7066e59c348adf379ee86 Mon Sep 17 00:00:00 2001 From: boiledegg Date: Wed, 10 Jul 2024 17:36:25 +0900 Subject: [PATCH 11/14] =?UTF-8?q?[ADD/#38]=20ScrapBox=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designsystem/component/box/ScrapBox.kt | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 core/src/main/java/com/terning/core/designsystem/component/box/ScrapBox.kt diff --git a/core/src/main/java/com/terning/core/designsystem/component/box/ScrapBox.kt b/core/src/main/java/com/terning/core/designsystem/component/box/ScrapBox.kt new file mode 100644 index 000000000..20e63380e --- /dev/null +++ b/core/src/main/java/com/terning/core/designsystem/component/box/ScrapBox.kt @@ -0,0 +1,95 @@ +package com.terning.core.designsystem.component.box + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.shadow +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.terning.core.designsystem.theme.CalPink +import com.terning.core.designsystem.theme.CalPurple +import com.terning.core.designsystem.theme.Grey150 +import com.terning.core.designsystem.theme.White + +@Composable +fun ScrapBox( + cornerRadius: Dp, + scrapColor: Color, + modifier: Modifier = Modifier, + elevation: Dp = 0.dp, + borderWidth: Dp = 0.dp, + borderColor: Color = Grey150, + content: @Composable () -> Unit, +) { + Box( + modifier = modifier + .border( + width = borderWidth, + color = borderColor, + RoundedCornerShape(cornerRadius), + ) + .shadow( + elevation = elevation, + RoundedCornerShape(cornerRadius), + ) + ) { + Box( + modifier = Modifier + .background( + color = scrapColor, + shape = RoundedCornerShape(cornerRadius) + ) + .fillMaxSize() + ) + Box( + modifier = Modifier + .fillMaxSize() + .padding(start = 9.dp) + .background( + shape = RoundedCornerShape( + topEnd = cornerRadius, bottomEnd = cornerRadius + ), color = White + ) + ) { + content() + } + } +} + +@Preview(showBackground = true, showSystemUi = true) +@Composable +fun ScrapBoxPreview() { + Column { + ScrapBox( + modifier = Modifier + .height(116.dp) + .width(140.dp), + scrapColor = CalPink, + cornerRadius = 5.dp, + borderWidth = 1.dp + ) {} + + Spacer(modifier = Modifier.height(10.dp)) + + ScrapBox( + modifier = Modifier + .height(height = 92.dp) + .fillMaxWidth(), + scrapColor = CalPurple, + cornerRadius = 10.dp, + elevation = 1.dp + ) {} + } +} \ No newline at end of file From d10d5477dcbf54a0556b0cd62f3af27efe46e03a Mon Sep 17 00:00:00 2001 From: boiledegg Date: Wed, 10 Jul 2024 17:37:02 +0900 Subject: [PATCH 12/14] =?UTF-8?q?[ADD/#38]=20=EC=A3=BC=EC=84=9D=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../terning/core/designsystem/component/box/ScrapBox.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/src/main/java/com/terning/core/designsystem/component/box/ScrapBox.kt b/core/src/main/java/com/terning/core/designsystem/component/box/ScrapBox.kt index 20e63380e..f47153360 100644 --- a/core/src/main/java/com/terning/core/designsystem/component/box/ScrapBox.kt +++ b/core/src/main/java/com/terning/core/designsystem/component/box/ScrapBox.kt @@ -23,6 +23,14 @@ import com.terning.core.designsystem.theme.CalPurple import com.terning.core.designsystem.theme.Grey150 import com.terning.core.designsystem.theme.White +/** + * ScrapBox is made for easy customization of scrap box used in Calendar & Home Screen + * + * [modifier] must be assigned for assigning size of the box and padding + * [elevation] must be set greater than zero for shadow effect, mainly used in Calendar + * [borderWidth] must be set greater than zero for border effect, mainly used in Home + */ + @Composable fun ScrapBox( cornerRadius: Dp, From 3b9c59f49bb15fbedd74c696ac69f70e6e25367e Mon Sep 17 00:00:00 2001 From: boiledegg Date: Wed, 10 Jul 2024 18:01:26 +0900 Subject: [PATCH 13/14] =?UTF-8?q?[CHORE/#38]=20=ED=94=84=EB=A6=AC=EB=B7=B0?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designsystem/component/box/ScrapBox.kt | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/com/terning/core/designsystem/component/box/ScrapBox.kt b/core/src/main/java/com/terning/core/designsystem/component/box/ScrapBox.kt index f47153360..03c6eb7f7 100644 --- a/core/src/main/java/com/terning/core/designsystem/component/box/ScrapBox.kt +++ b/core/src/main/java/com/terning/core/designsystem/component/box/ScrapBox.kt @@ -76,28 +76,28 @@ fun ScrapBox( } } -@Preview(showBackground = true, showSystemUi = true) +@Preview(showBackground = true) @Composable -fun ScrapBoxPreview() { - Column { - ScrapBox( - modifier = Modifier - .height(116.dp) - .width(140.dp), - scrapColor = CalPink, - cornerRadius = 5.dp, - borderWidth = 1.dp - ) {} - - Spacer(modifier = Modifier.height(10.dp)) +fun BorderedScrapBoxPreview() { + ScrapBox( + modifier = Modifier + .height(116.dp) + .width(140.dp), + scrapColor = CalPink, + cornerRadius = 5.dp, + borderWidth = 1.dp + ) {} +} - ScrapBox( - modifier = Modifier - .height(height = 92.dp) - .fillMaxWidth(), - scrapColor = CalPurple, - cornerRadius = 10.dp, - elevation = 1.dp - ) {} - } +@Preview(showBackground = true) +@Composable +fun ShadowedScrapBoxPreview() { + ScrapBox( + modifier = Modifier + .height(height = 92.dp) + .fillMaxWidth(), + scrapColor = CalPurple, + cornerRadius = 10.dp, + elevation = 1.dp + ) {} } \ No newline at end of file From 067947a7559b1f31a7e68bceb95498328fd3a4d3 Mon Sep 17 00:00:00 2001 From: boiledegg Date: Wed, 10 Jul 2024 18:52:15 +0900 Subject: [PATCH 14/14] =?UTF-8?q?[REFACTOR/#20]=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EA=B8=B0=EB=B0=98=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/terning/feature/calendar/CalendarRoute.kt | 3 ++- .../com/terning/feature/calendar/CalendarWeekWithScrap.kt | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt index 03afb65e3..827f8d416 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarRoute.kt @@ -29,6 +29,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.terning.core.designsystem.theme.Grey200 import com.terning.feature.R import com.terning.feature.calendar.component.CalendarTopBar @@ -48,7 +49,7 @@ fun CalendarScreen( modifier: Modifier = Modifier, viewModel: CalendarViewModel = hiltViewModel() ) { - val selectedDate by viewModel.selectedDate.collectAsState() + val selectedDate by viewModel.selectedDate.collectAsStateWithLifecycle() val state by remember { mutableStateOf(CalendarState()) } val listState = rememberLazyListState( diff --git a/feature/src/main/java/com/terning/feature/calendar/CalendarWeekWithScrap.kt b/feature/src/main/java/com/terning/feature/calendar/CalendarWeekWithScrap.kt index 00a1adde4..fbdf774cc 100644 --- a/feature/src/main/java/com/terning/feature/calendar/CalendarWeekWithScrap.kt +++ b/feature/src/main/java/com/terning/feature/calendar/CalendarWeekWithScrap.kt @@ -29,7 +29,10 @@ fun CalendarWeekWithScrap( ) { Card( modifier = Modifier - .border(0.dp, Grey200, RoundedCornerShape(bottomStart = 20.dp, bottomEnd = 20.dp)) + .border( + width = 0.dp, + color = Grey200, + shape = RoundedCornerShape(bottomStart = 20.dp, bottomEnd = 20.dp)) .shadow( shape = RoundedCornerShape(bottomStart = 20.dp, bottomEnd = 20.dp), elevation = 1.dp @@ -49,7 +52,7 @@ fun CalendarWeekWithScrap( LazyColumn( modifier = Modifier .fillMaxWidth() - ){ + ) { /*items(items = scrapLists[selectedDate?.dayOfMonth - 1]) { }*/