Skip to content

Commit

Permalink
Merge pull request #10 from lampione/feature/fixStartAtMaxPage
Browse files Browse the repository at this point in the history
chore: fix edge case when startDate = maxDate
  • Loading branch information
lampione authored Oct 14, 2022
2 parents 8dac6ba + a1a61dd commit 8a8cd19
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@

package com.squaredem.composecalendar.composable

import android.util.Log
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
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.rememberLazyGridState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
Expand All @@ -30,7 +29,6 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.text.font.FontWeight
Expand All @@ -50,7 +48,6 @@ import java.time.LocalDate
import java.time.format.TextStyle
import java.util.*
import kotlin.math.abs
import kotlin.math.absoluteValue
import kotlin.math.ceil
import kotlin.math.floor

Expand All @@ -70,7 +67,10 @@ internal fun CalendarContent(
val initialPage = getStartPage(startDate, dateRange, totalPageCount)

val isPickingYear = remember { mutableStateOf(false) }

// for display only, used in CalendarMonthYearSelector
val currentPagerDate = remember { mutableStateOf(startDate.withDayOfMonth(1)) }

val selectedDate = remember { mutableStateOf(startDate) }

val pagerState = rememberPagerState(initialPage)
Expand All @@ -87,17 +87,8 @@ internal fun CalendarContent(
if (!LocalInspectionMode.current) {
LaunchedEffect(pagerState) {
snapshotFlow { pagerState.targetPage }.collect { page ->
val pageDiff = page.minus(initialPage).absoluteValue.toLong()

val date = if (page > initialPage) {
startDate.plusMonths(pageDiff)
} else if (page < initialPage) {
startDate.minusMonths(pageDiff)
} else {
startDate
}

currentPagerDate.value = date
val currentDate = getDateFromCurrentPage(page, dateRange)
currentPagerDate.value = currentDate
}
}
}
Expand All @@ -109,12 +100,27 @@ internal fun CalendarContent(
CalendarTopBar(selectedDate.value)

CalendarMonthYearSelector(
coroutineScope,
pagerState,
currentPagerDate.value
) {
isPickingYear.value = !isPickingYear.value
}
currentPagerDate.value,
onChipClicked = { isPickingYear.value = !isPickingYear.value },
onNextMonth = {
coroutineScope.launch {
try {
pagerState.animateScrollToPage(pagerState.currentPage + 1)
} catch (e: Exception) {
// avoid IndexOutOfBounds and animation crashes
}
}
},
onPreviousMonth = {
coroutineScope.launch {
try {
pagerState.animateScrollToPage(pagerState.currentPage - 1)
} catch (e: Exception) {
// avoid IndexOutOfBounds and animation crashes
}
}
}
)

if (!isPickingYear.value) {

Expand All @@ -139,24 +145,18 @@ internal fun CalendarContent(
count = totalPageCount,
state = pagerState
) { page ->
val pageDiff = page.minus(initialPage).absoluteValue.toLong()

val date = if (page > initialPage) {
startDate.plusMonths(pageDiff)
} else if (page < initialPage) {
startDate.minusMonths(pageDiff)
} else {
startDate
val currentDate = getDateFromCurrentPage(page, dateRange)

currentDate?.let {
// grid
CalendarGrid(
it.withDayOfMonth(1),
dateRange,
selectedDate.value,
setSelectedDate,
true
)
}

// grid
CalendarGrid(
date.withDayOfMonth(1),
dateRange,
selectedDate.value,
setSelectedDate,
true
)
}

} else {
Expand Down Expand Up @@ -217,6 +217,17 @@ private fun getDateRange(min: LocalDate, max: LocalDate): DateRange {
return lowerBound.rangeTo(upperBound) step DateRangeStep.Month()
}

private fun getDateFromCurrentPage(
currentPage: Int,
dateRange: DateRange,
): LocalDate? {
return try {
dateRange.elementAt(currentPage)
} catch (e: Exception) {
null
}
}

@Preview(showBackground = true)
@Composable
private fun Preview() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,18 @@ import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.PagerState
import com.squaredem.composecalendar.utils.LogCompositions
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.time.LocalDate
import java.time.OffsetTime
import java.util.*

@OptIn(ExperimentalPagerApi::class, ExperimentalMaterial3Api::class)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
internal fun CalendarMonthYearSelector(
coroutineScope: CoroutineScope,
pagerState: PagerState,
pagerDate: LocalDate,
onChipClicked: () -> Unit
onChipClicked: () -> Unit,
onNextMonth: () -> Unit,
onPreviousMonth: () -> Unit
) {
LogCompositions("CalendarMonthYearSelector")

Expand All @@ -73,39 +72,11 @@ internal fun CalendarMonthYearSelector(
onClick = onChipClicked,
)
Spacer(modifier = Modifier.weight(1F))
IconButton(
onClick = {
coroutineScope.launch {
with(pagerState) {
try {
animateScrollToPage(currentPage - 1)
} catch (e: Exception) {
// avoid IOOB and animation crashes
}
}
}
}
) {
Icon(
Icons.Default.ChevronLeft, "ChevronLeft"
)
IconButton(onClick = onPreviousMonth) {
Icon(Icons.Default.ChevronLeft, "ChevronLeft")
}
IconButton(
onClick = {
coroutineScope.launch {
with(pagerState) {
try {
animateScrollToPage(currentPage + 1)
} catch (e: Exception) {
// avoid IOOB and animation crashes
}
}
}
}
) {
Icon(
Icons.Default.ChevronRight, "ChevronRight",
)
IconButton(onClick = onNextMonth) {
Icon(Icons.Default.ChevronRight, "ChevronRight")
}
}
}

0 comments on commit 8a8cd19

Please sign in to comment.