Skip to content

Commit

Permalink
[#10] Mark a list dates (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
mateusz800 committed May 24, 2024
1 parent c5deac6 commit 759df73
Show file tree
Hide file tree
Showing 13 changed files with 113 additions and 27 deletions.
19 changes: 18 additions & 1 deletion app/src/main/java/com/mabn/calendar/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import com.mabn.calendarlibrary.ExpandableCalendar
import com.mabn.calendar.ui.theme.CalendarTheme
import com.mabn.calendarlibrary.core.calendarDefaultTheme
import com.mabn.calendarlibrary.core.model.DatesGroup
import com.mabn.calendarlibrary.core.model.calendarDefaultTheme
import java.time.LocalDate

class MainActivity : ComponentActivity() {
Expand All @@ -45,8 +46,10 @@ class MainActivity : ComponentActivity() {
fun Calendar() {
val currentDate = remember { mutableStateOf(LocalDate.now()) }
val scrollState = rememberScrollState()
val datesGroup = prepareExampleDateGroups()
Column(Modifier.verticalScroll(scrollState)) {
ExpandableCalendar(
datesGroups = datesGroup,
theme = calendarDefaultTheme.copy(
dayShape = CircleShape,
backgroundColor = Color.Black,
Expand All @@ -64,6 +67,20 @@ fun Calendar() {
}
}

fun prepareExampleDateGroups(): List<DatesGroup> {
val markedDatesGroup1 = DatesGroup(dates = listOf(
LocalDate.now().minusDays(1),
LocalDate.now().minusDays(2),
LocalDate.now().minusDays(5)
), color = Color.Cyan)
val markedDatesGroup2 = DatesGroup(dates = listOf(
LocalDate.now().plusDays(3),
LocalDate.now().minusWeeks(1)
), color = Color.Yellow)

return listOf(markedDatesGroup1, markedDatesGroup2)
}


@Preview(showBackground = true)
@Composable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.test.*
import androidx.compose.ui.test.junit4.createComposeRule
import com.mabn.calendarlibrary.component.DayView
import com.mabn.calendarlibrary.core.calendarDefaultTheme
import com.mabn.calendarlibrary.components.DayView
import com.mabn.calendarlibrary.core.model.calendarDefaultTheme
import com.mabn.calendarlibrary.utils.getBackgroundColor
import org.junit.*
import org.junit.runners.MethodSorters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.mabn.calendarlibrary.core.CalendarIntent
import com.mabn.calendarlibrary.core.DateTimeConstants
import com.mabn.calendarlibrary.core.Period
import com.mabn.calendarlibrary.core.RelativePosition
import com.mabn.calendarlibrary.core.model.DatesGroup
import com.mabn.calendarlibrary.utils.*
import com.mabn.calendarlibrary.utils.getNextDates
import com.mabn.calendarlibrary.utils.getRemainingDatesInWeek
Expand All @@ -16,7 +17,7 @@ import kotlinx.coroutines.launch
import java.time.LocalDate
import java.time.YearMonth

class CalendarViewModel : ViewModel() {
class CalendarViewModel(private val datesGroups: List<DatesGroup>) : ViewModel() {

private val _visibleDates =
MutableStateFlow(
Expand Down Expand Up @@ -49,6 +50,9 @@ class CalendarViewModel : ViewModel() {
private val _calendarExpanded = MutableStateFlow(false)
val calendarExpanded: StateFlow<Boolean> = _calendarExpanded

private val _visibleDatesInGroups = MutableStateFlow(datesGroups)
val visibleDatesInGroups: StateFlow<List<DatesGroup>> = _visibleDatesInGroups


fun onIntent(intent: CalendarIntent) {
when (intent) {
Expand Down Expand Up @@ -89,11 +93,18 @@ class CalendarViewModel : ViewModel() {
period: Period = Period.WEEK
) {
viewModelScope.launch(Dispatchers.IO) {
val dates = when (period) {
Period.WEEK -> calculateCollapsedCalendarDays(startDate)
Period.MONTH -> calculateExpandedCalendarDays(startDate)
}
_visibleDates.emit(
when (period) {
Period.WEEK -> calculateCollapsedCalendarDays(startDate)
Period.MONTH -> calculateExpandedCalendarDays(startDate)
}
dates
)
_visibleDatesInGroups.emit(
filterDatesGroups(
dates[RelativePosition.CURRENT.ordinal].first(),
dates[RelativePosition.CURRENT.ordinal].last()
)
)
}
}
Expand All @@ -108,7 +119,8 @@ class CalendarViewModel : ViewModel() {
}

private fun calculateCollapsedCalendarDays(startDate: LocalDate): Array<List<LocalDate>> {
val dates = startDate.getNextDates(RelativePosition.values().size * DateTimeConstants.DAYS_IN_WEEK)
val dates =
startDate.getNextDates(RelativePosition.values().size * DateTimeConstants.DAYS_IN_WEEK)
return Array(RelativePosition.values().size) {
dates.slice(it * DateTimeConstants.DAYS_IN_WEEK until (it + 1) * DateTimeConstants.DAYS_IN_WEEK)
}
Expand All @@ -129,4 +141,11 @@ class CalendarViewModel : ViewModel() {
}
return array
}

private fun filterDatesGroups(startDate: LocalDate, endDate: LocalDate): List<DatesGroup> {
return datesGroups.map {
val dates = it.dates.filter { date -> date in startDate..endDate }
DatesGroup(dates = dates, color = it.color)
}.toList()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,39 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.mabn.calendarlibrary.component.InlineCalendar
import com.mabn.calendarlibrary.component.MonthText
import com.mabn.calendarlibrary.component.MonthViewCalendar
import com.mabn.calendarlibrary.component.ToggleExpandCalendarButton
import com.mabn.calendarlibrary.components.InlineCalendar
import com.mabn.calendarlibrary.components.MonthText
import com.mabn.calendarlibrary.components.MonthViewCalendar
import com.mabn.calendarlibrary.components.ToggleExpandCalendarButton
import com.mabn.calendarlibrary.core.CalendarIntent
import com.mabn.calendarlibrary.core.CalendarTheme
import com.mabn.calendarlibrary.core.model.CalendarTheme
import com.mabn.calendarlibrary.core.Period
import com.mabn.calendarlibrary.core.calendarDefaultTheme
import com.mabn.calendarlibrary.core.model.DatesGroup
import com.mabn.calendarlibrary.core.model.calendarDefaultTheme
import com.mabn.calendarlibrary.utils.CalendarViewModelFactory
import com.mabn.calendarlibrary.utils.getWeekStartDate
import java.time.LocalDate
import java.time.YearMonth

@Composable
fun ExpandableCalendar(
onDayClick: (LocalDate) -> Unit,
datesGroups: List<DatesGroup> = listOf(),
theme: CalendarTheme = calendarDefaultTheme
) {
val viewModel: CalendarViewModel = viewModel()
val viewModel: CalendarViewModel = viewModel(factory = CalendarViewModelFactory(datesGroups))
val loadedDates = viewModel.visibleDates.collectAsState()
val selectedDate = viewModel.selectedDate.collectAsState()
val calendarExpanded = viewModel.calendarExpanded.collectAsState()
val currentMonth = viewModel.currentMonth.collectAsState()
val visibleDatesInGroup = viewModel.visibleDatesInGroups.collectAsState()
ExpandableCalendar(
loadedDates = loadedDates.value,
selectedDate = selectedDate.value,
currentMonth = currentMonth.value,
onIntent = viewModel::onIntent,
calendarExpanded = calendarExpanded.value,
datesGroups = visibleDatesInGroup.value,
theme = theme,
onDayClick = onDayClick
)
Expand All @@ -53,6 +58,7 @@ private fun ExpandableCalendar(
currentMonth: YearMonth,
onIntent: (CalendarIntent) -> Unit,
calendarExpanded: Boolean,
datesGroups: List<DatesGroup>,
theme: CalendarTheme,
onDayClick: (LocalDate) -> Unit
) {
Expand Down Expand Up @@ -94,6 +100,7 @@ private fun ExpandableCalendar(
)
)
},
datesGroups = datesGroups,
onDayClick = {
onIntent(CalendarIntent.SelectDate(it))
onDayClick(it)
Expand All @@ -103,6 +110,7 @@ private fun ExpandableCalendar(
InlineCalendar(
loadedDates,
selectedDate,
datesGroups = datesGroups,
theme = theme,
loadNextWeek = { nextWeekDate -> onIntent(CalendarIntent.LoadNextDates(nextWeekDate)) },
loadPrevWeek = { endWeekDate ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.mabn.calendarlibrary.component
package com.mabn.calendarlibrary.components

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package com.mabn.calendarlibrary.component
package com.mabn.calendarlibrary.components

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.mabn.calendarlibrary.core.CalendarTheme
import com.mabn.calendarlibrary.core.model.CalendarTheme
import java.time.DayOfWeek
import java.time.LocalDate
import java.time.format.TextStyle
Expand All @@ -31,6 +34,7 @@ fun DayView(
theme: CalendarTheme,
modifier: Modifier = Modifier,
isSelected: Boolean = false,
markedColor: Color? = null,
weekDayLabel: Boolean = true
) {
val isCurrentDay = date == LocalDate.now()
Expand All @@ -44,6 +48,7 @@ fun DayView(
shape = theme.dayShape
)
else modifier.background(theme.dayBackgroundColor, shape = theme.dayShape)

Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
Expand Down Expand Up @@ -76,6 +81,14 @@ fun DayView(
textAlign = TextAlign.Center,
color = if (isSelected || isCurrentDay) theme.selectedDayValueTextColor else theme.dayValueTextColor
)
with(LocalDensity.current) {
markedColor?.let {
Modifier
.padding(top = 32.sp.toDp())
.size(10.dp)
.background(color = it, shape = CircleShape)
}?.let { Box(modifier = it) }
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.mabn.calendarlibrary.component
package com.mabn.calendarlibrary.components

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
Expand All @@ -9,15 +9,17 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.unit.dp
import com.mabn.calendarlibrary.core.CalendarTheme
import com.mabn.calendarlibrary.core.model.CalendarTheme
import com.mabn.calendarlibrary.core.DateTimeConstants
import com.mabn.calendarlibrary.core.model.DatesGroup
import com.mabn.calendarlibrary.utils.dayViewModifier
import java.time.LocalDate

@Composable
internal fun InlineCalendar(
loadedDates: Array<List<LocalDate>>,
selectedDate: LocalDate,
datesGroups: List<DatesGroup>,
theme: CalendarTheme,
loadNextWeek: (nextWeekDate: LocalDate) -> Unit,
loadPrevWeek: (endWeekDate: LocalDate) -> Unit,
Expand All @@ -32,6 +34,7 @@ internal fun InlineCalendar(
Row {
loadedDates[currentPage]
.forEach { date ->
val markedColor = datesGroups.find { it.dates.contains(date) }?.color
Box(
modifier = Modifier
.width(itemWidth.dp)
Expand All @@ -42,6 +45,7 @@ internal fun InlineCalendar(
date,
theme = theme,
isSelected = selectedDate == date,
markedColor = markedColor,
onDayClick = onDayClick,
modifier = Modifier.dayViewModifier(date)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.mabn.calendarlibrary.component
package com.mabn.calendarlibrary.components

import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
import com.mabn.calendarlibrary.core.CalendarTheme
import com.mabn.calendarlibrary.core.model.CalendarTheme
import java.time.YearMonth
import java.time.format.TextStyle

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.mabn.calendarlibrary.component
package com.mabn.calendarlibrary.components

import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
Expand All @@ -7,8 +7,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.unit.dp
import com.google.accompanist.flowlayout.FlowRow
import com.mabn.calendarlibrary.core.CalendarTheme
import com.mabn.calendarlibrary.core.model.CalendarTheme
import com.mabn.calendarlibrary.core.DateTimeConstants
import com.mabn.calendarlibrary.core.model.DatesGroup
import com.mabn.calendarlibrary.utils.dayViewModifier
import java.time.LocalDate
import java.time.YearMonth
Expand All @@ -19,6 +20,7 @@ internal fun MonthViewCalendar(
selectedDate: LocalDate,
theme: CalendarTheme,
currentMonth: YearMonth,
datesGroups: List<DatesGroup>,
loadDatesForMonth: (YearMonth) -> Unit,
onDayClick: (LocalDate) -> Unit
) {
Expand All @@ -30,6 +32,8 @@ internal fun MonthViewCalendar(
) { currentPage ->
FlowRow(Modifier.height(355.dp)) {
loadedDates[currentPage].forEachIndexed { index, date ->
val markedColor = datesGroups.find { it.dates.contains(date) }?.color

Box(
Modifier
.width(itemWidth.dp)
Expand All @@ -40,6 +44,7 @@ internal fun MonthViewCalendar(
date,
theme = theme,
isSelected = selectedDate == date,
markedColor = markedColor,
onDayClick = { onDayClick(date) },
weekDayLabel = index < DateTimeConstants.DAYS_IN_WEEK,
modifier = Modifier.dayViewModifier(date, currentMonth, monthView = true)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.mabn.calendarlibrary.component
package com.mabn.calendarlibrary.components

import androidx.compose.material.Icon
import androidx.compose.material.IconToggleButton
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.mabn.calendarlibrary.core
package com.mabn.calendarlibrary.core.model

import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.mabn.calendarlibrary.core.model

import androidx.compose.ui.graphics.Color
import java.time.LocalDate

data class DatesGroup(
val dates: List<LocalDate>,
val color: Color,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.mabn.calendarlibrary.utils

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.mabn.calendarlibrary.CalendarViewModel
import com.mabn.calendarlibrary.core.model.DatesGroup

class CalendarViewModelFactory(private val datesGroups: List<DatesGroup>):
ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T = CalendarViewModel(datesGroups) as T
}

0 comments on commit 759df73

Please sign in to comment.