diff --git a/feature/filtering/src/main/java/com/terning/feature/filtering/filteringthree/FilteringThreeRoute.kt b/feature/filtering/src/main/java/com/terning/feature/filtering/filteringthree/FilteringThreeRoute.kt index d10a9298..c31df2fc 100644 --- a/feature/filtering/src/main/java/com/terning/feature/filtering/filteringthree/FilteringThreeRoute.kt +++ b/feature/filtering/src/main/java/com/terning/feature/filtering/filteringthree/FilteringThreeRoute.kt @@ -35,7 +35,7 @@ import com.terning.core.designsystem.theme.TerningPointTheme import com.terning.core.designsystem.theme.TerningTheme import com.terning.core.designsystem.theme.White import com.terning.feature.filtering.R -import com.terning.feature.filtering.filteringthree.component.YearMonthPicker +import com.terning.feature.filtering.filteringthree.component.FilteringYearMonthPicker import java.util.Calendar @Composable @@ -147,7 +147,7 @@ fun FilteringThreeScreen( ) ) Spacer(modifier = Modifier.height(61.dp)) - YearMonthPicker( + FilteringYearMonthPicker( chosenYear = chosenYear, chosenMonth = chosenMonth, onYearChosen = { onYearChosen(it) }, diff --git a/feature/filtering/src/main/java/com/terning/feature/filtering/filteringthree/component/YearMonthPicker.kt b/feature/filtering/src/main/java/com/terning/feature/filtering/filteringthree/component/FilteringYearMonthPicker.kt similarity index 99% rename from feature/filtering/src/main/java/com/terning/feature/filtering/filteringthree/component/YearMonthPicker.kt rename to feature/filtering/src/main/java/com/terning/feature/filtering/filteringthree/component/FilteringYearMonthPicker.kt index 9e870d11..5e77b1ba 100644 --- a/feature/filtering/src/main/java/com/terning/feature/filtering/filteringthree/component/YearMonthPicker.kt +++ b/feature/filtering/src/main/java/com/terning/feature/filtering/filteringthree/component/FilteringYearMonthPicker.kt @@ -56,7 +56,7 @@ class PickerState { fun rememberPickerState() = remember { PickerState() } @Composable -fun YearMonthPicker( +fun FilteringYearMonthPicker( modifier: Modifier = Modifier, chosenYear: Int, chosenMonth: Int, diff --git a/feature/home/src/main/java/com/terning/feature/home/component/HomeFilteringBottomSheet.kt b/feature/home/src/main/java/com/terning/feature/home/component/HomeFilteringBottomSheet.kt index 27fb6e5b..47d7df74 100644 --- a/feature/home/src/main/java/com/terning/feature/home/component/HomeFilteringBottomSheet.kt +++ b/feature/home/src/main/java/com/terning/feature/home/component/HomeFilteringBottomSheet.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.itemsIndexed +import androidx.compose.material3.Checkbox import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Text @@ -21,6 +22,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import com.terning.core.designsystem.R import com.terning.core.designsystem.component.bottomsheet.TerningBasicBottomSheet import com.terning.core.designsystem.component.button.ChangeFilterButton import com.terning.core.designsystem.component.button.RoundButton @@ -31,7 +33,7 @@ import com.terning.core.designsystem.theme.Grey200 import com.terning.core.designsystem.theme.TerningTheme import com.terning.core.designsystem.type.Grade import com.terning.core.designsystem.type.WorkingPeriod -import com.terning.core.designsystem.R +import kotlinx.collections.immutable.toImmutableList import java.util.Calendar @OptIn(ExperimentalMaterial3Api::class) @@ -60,6 +62,26 @@ fun HomeFilteringBottomSheet( ) } + var isYearNull by remember { mutableStateOf(defaultStartYear != null) } + var isMonthNull by remember { mutableStateOf(defaultStartMonth != null) } + + var isCheckBoxChecked by remember { mutableStateOf(false) } + + var isInitialNullState by remember { mutableStateOf(false) } + + val yearsList by remember(isYearNull) { + mutableStateOf( + if (isYearNull || isInitialNullState) years + NULL_DATE + else years + ) + } + val monthsList by remember(isMonthNull) { + mutableStateOf( + if (isMonthNull || isInitialNullState) months + NULL_DATE + else months + ) + } + TerningBasicBottomSheet( content = { Column( @@ -132,13 +154,45 @@ fun HomeFilteringBottomSheet( .padding(horizontal = 24.dp) ) - YearMonthPicker( - chosenYear = defaultStartYear ?: Calendar.getInstance().currentYear, - chosenMonth = defaultStartMonth - ?: Calendar.getInstance().currentMonth, - onYearChosen = { currentStartYear = it }, - onMonthChosen = { currentStartMonth = it } + //TODO: 아래는 임시 체크박스로, 추후 수정 부탁합니다! + Checkbox( + checked = isCheckBoxChecked, + onCheckedChange = { isChecked -> + if (isChecked) { + isYearNull = true + isMonthNull = true + } + isCheckBoxChecked = isChecked + }, + modifier = Modifier.padding(start = 20.dp) + ) + + HomeYearMonthPicker( + chosenYear = defaultStartYear, + chosenMonth = defaultStartMonth, + onYearChosen = { year, isInitialSelection -> + if (year != null) { + currentStartYear = year + isCheckBoxChecked = false + isYearNull = false + isInitialNullState = isInitialSelection + } + }, + onMonthChosen = { month, isInitialSelection -> + if (month != null) { + currentStartMonth = month + isCheckBoxChecked = false + isMonthNull = false + isInitialNullState = isInitialSelection + } + }, + isYearNull = isYearNull, + isMonthNull = isMonthNull, + yearsList = yearsList.toImmutableList(), + monthsList = monthsList.toImmutableList(), + isInitialNullState = isInitialNullState ) + RoundButton( style = TerningTheme.typography.button0, paddingVertical = 19.dp, @@ -162,7 +216,6 @@ fun HomeFilteringBottomSheet( isEnabled = currentGrade != null && currentPeriod != null ) } - }, onDismissRequest = onDismiss, sheetState = sheetState, diff --git a/feature/home/src/main/java/com/terning/feature/home/component/YearMonthPicker.kt b/feature/home/src/main/java/com/terning/feature/home/component/HomeYearMonthPicker.kt similarity index 74% rename from feature/home/src/main/java/com/terning/feature/home/component/YearMonthPicker.kt rename to feature/home/src/main/java/com/terning/feature/home/component/HomeYearMonthPicker.kt index 1771bc4b..d1f613ea 100644 --- a/feature/home/src/main/java/com/terning/feature/home/component/YearMonthPicker.kt +++ b/feature/home/src/main/java/com/terning/feature/home/component/HomeYearMonthPicker.kt @@ -38,15 +38,14 @@ import com.terning.core.designsystem.util.CalendarDefaults.END_MONTH import com.terning.core.designsystem.util.CalendarDefaults.END_YEAR import com.terning.core.designsystem.util.CalendarDefaults.START_MONTH import com.terning.core.designsystem.util.CalendarDefaults.START_YEAR +import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map -import okhttp3.internal.toImmutableList -private val years = - (START_YEAR..END_YEAR).map { "${it}년" }.toImmutableList() +val years = (START_YEAR..END_YEAR).map { "${it}년" } +val months = (START_MONTH..END_MONTH).map { "${it}월" } -private val months = - (START_MONTH..END_MONTH).map { "${it}월" }.toImmutableList() +const val NULL_DATE = "-" class PickerState { var selectedItem by mutableStateOf("") @@ -56,26 +55,29 @@ class PickerState { fun rememberPickerState() = remember { PickerState() } @Composable -fun YearMonthPicker( +fun HomeYearMonthPicker( modifier: Modifier = Modifier, - chosenYear: Int, - chosenMonth: Int, - onYearChosen: (Int) -> Unit, - onMonthChosen: (Int) -> Unit, + chosenYear: Int?, + chosenMonth: Int?, + onYearChosen: (Int?, Boolean) -> Unit, + onMonthChosen: (Int?, Boolean) -> Unit, + isYearNull: Boolean, + isMonthNull: Boolean, + yearsList: ImmutableList, + monthsList: ImmutableList, + isInitialNullState: Boolean ) { val yearPickerState = rememberPickerState() val monthPickerState = rememberPickerState() - val startYearIndex = years.indexOf("${chosenYear}년").takeIf { it >= 0 } ?: 0 - val startMonthIndex = months.indexOf("${chosenMonth}월").takeIf { it >= 0 } ?: 0 + var isInitialSelection by remember { mutableStateOf(isInitialNullState) } - LaunchedEffect(chosenYear) { - yearPickerState.selectedItem = "${chosenYear}년" - } - - LaunchedEffect(chosenMonth) { - monthPickerState.selectedItem = "${chosenMonth}월" - } + val startYearIndex = + if (isYearNull) yearsList.lastIndex else yearsList.indexOf("${chosenYear ?: "-"}년") + .takeIf { it >= 0 } ?: 0 + val startMonthIndex = + if (isMonthNull) monthsList.lastIndex else monthsList.indexOf("${chosenMonth ?: "-"}월") + .takeIf { it >= 0 } ?: 0 Row( modifier = modifier @@ -86,20 +88,28 @@ fun YearMonthPicker( DatePicker( modifier = Modifier.weight(1f), pickerState = yearPickerState, - items = years, + items = yearsList, startIndex = startYearIndex, onItemSelected = { year -> - onYearChosen(year.dropLast(1).toInt()) + if (year == NULL_DATE && !isInitialSelection) isInitialSelection = true + onYearChosen( + if (year == NULL_DATE) null else year.dropLast(1).toInt(), + isInitialSelection + ) } ) Spacer(modifier = Modifier.width(18.dp)) DatePicker( modifier = Modifier.weight(1f), pickerState = monthPickerState, - items = months, + items = monthsList, startIndex = startMonthIndex, onItemSelected = { month -> - onMonthChosen(month.dropLast(1).toInt()) + if (month == NULL_DATE && !isInitialSelection) isInitialSelection = true + onMonthChosen( + if (month == NULL_DATE) null else month.dropLast(1).toInt(), + isInitialSelection + ) } ) } @@ -107,7 +117,7 @@ fun YearMonthPicker( @Composable fun DatePicker( - items: List, + items: ImmutableList, modifier: Modifier = Modifier, pickerState: PickerState = rememberPickerState(), startIndex: Int = 0, @@ -121,13 +131,18 @@ fun DatePicker( val scrollState = rememberLazyListState(initialFirstVisibleItemIndex = startIndex) val flingBehavior = rememberSnapFlingBehavior(lazyListState = scrollState) - LaunchedEffect(itemHeightPixel) { - if (itemHeightPixel > 0) scrollState.scrollToItem(startIndex) + LaunchedEffect(itemHeightPixel, startIndex) { + if (itemHeightPixel > 0 && startIndex >= 0) scrollState.scrollToItem(startIndex) } LaunchedEffect(scrollState) { snapshotFlow { scrollState.firstVisibleItemIndex } - .map { index -> items.getOrNull(index) } + .map { index -> + val hasNullDate = + items.size == (END_YEAR - START_YEAR + 1) || items.size == (END_MONTH - START_MONTH + 1) + val adjustedItems = if (hasNullDate) items + NULL_DATE else items + adjustedItems.getOrNull(index) + } .distinctUntilChanged() .collect { item -> item?.let { diff --git a/feature/main/src/main/java/com/terning/feature/main/MainScreen.kt b/feature/main/src/main/java/com/terning/feature/main/MainScreen.kt index 643c5ce1..2a741d9f 100644 --- a/feature/main/src/main/java/com/terning/feature/main/MainScreen.kt +++ b/feature/main/src/main/java/com/terning/feature/main/MainScreen.kt @@ -16,6 +16,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material3.Icon import androidx.compose.material3.NavigationBar import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.NavigationBarItemDefaults import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarDuration import androidx.compose.material3.SnackbarHost @@ -309,7 +310,7 @@ private fun MainBottomBar( fontSize = 9.sp ) }, - colors = androidx.compose.material3.NavigationBarItemDefaults + colors = NavigationBarItemDefaults .colors( selectedIconColor = TerningMain, selectedTextColor = TerningMain,