Skip to content

Commit 6a51209

Browse files
committed
feat: add a new month banner in the tasks list of the calendar
This improves the user experience by making it easier to keep track of where they are. I also deleted a not used drawable.
1 parent ce4f75d commit 6a51209

3 files changed

Lines changed: 100 additions & 46 deletions

File tree

feature/calendar/src/main/java/com/markel/flowstate/feature/calendar/components/taskslist/DailyTasksSection.kt

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import java.util.Locale
3535
import androidx.compose.ui.platform.LocalLocale
3636
import java.time.temporal.WeekFields
3737

38-
private const val DAYS_AHEAD = 90
38+
private const val DAYS_AHEAD = 180
3939
private val DAY_COLUMN_WIDTH = 56.dp
4040
private val firstDayOfWeek: DayOfWeek
4141
get() = WeekFields.of(Locale.getDefault()).firstDayOfWeek
@@ -48,7 +48,8 @@ private data class WeekBlock(
4848

4949
private data class DayBlock(
5050
val date: LocalDate,
51-
val tasks: List<Task>
51+
val tasks: List<Task>,
52+
val isFirstOfMonth: Boolean = false
5253
)
5354

5455
@Composable
@@ -87,28 +88,31 @@ private fun WeekSection(
8788
week: WeekBlock,
8889
onTaskToggle: (Task) -> Unit
8990
) {
90-
Row(
91-
modifier = Modifier
92-
.fillMaxWidth()
93-
.padding(top = 12.dp),
94-
verticalAlignment = Alignment.CenterVertically
95-
) {
96-
// Left column spacer — keeps week label aligned with task cards
97-
Spacer(modifier = Modifier.width(DAY_COLUMN_WIDTH))
98-
99-
// Week label sits directly above its day rows, in the same column as the cards
100-
Text(
101-
text = week.label,
102-
style = MaterialTheme.typography.labelMedium.copy(fontWeight = FontWeight.Medium),
103-
color = MaterialTheme.colorScheme.onSurfaceVariant,
104-
)
105-
}
91+
Column {
92+
Row(
93+
modifier = Modifier.fillMaxWidth().padding(top = 12.dp),
94+
verticalAlignment = Alignment.CenterVertically
95+
) {
96+
// Left column spacer — keeps week label aligned with task cards
97+
Spacer(modifier = Modifier.width(DAY_COLUMN_WIDTH))
98+
// Week label sits directly above its day rows, in the same column as the cards
99+
Text(
100+
text = week.label,
101+
style = MaterialTheme.typography.labelMedium,
102+
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.8f),
103+
)
104+
}
106105

107-
Spacer(modifier = Modifier.height(6.dp))
106+
Spacer(modifier = Modifier.height(6.dp))
108107

109-
if (week.days.isNotEmpty()) {
110108
week.days.forEach { day ->
111-
DayRow(day = day, onTaskToggle = onTaskToggle)
109+
if (day.isFirstOfMonth) {
110+
MonthBanner(day.date)
111+
}
112+
113+
if (day.tasks.isNotEmpty()) {
114+
DayRow(day = day, onTaskToggle = onTaskToggle)
115+
}
112116
}
113117
}
114118
}
@@ -194,24 +198,28 @@ private fun buildWeekBlocks(
194198
var weekStart = startDate.with(TemporalAdjusters.previousOrSame(firstDayOfWeek))
195199

196200
while (weekStart <= endDate) {
197-
val weekEnd = weekStart.plusDays(6)
198-
val days = (0L..6L)
199-
.map { weekStart.plusDays(it) }
200-
.filter { it in startDate..endDate }
201-
.mapNotNull { day ->
202-
tasksByDate[day]?.takeIf { it.isNotEmpty() }?.let { DayBlock(day, it) }
203-
}
204-
205-
blocks.add(
206-
WeekBlock(
207-
weekKey = weekKeyFor(weekStart),
208-
label = buildWeekLabel(weekStart, weekEnd),
209-
days = days
201+
val days = (0L..6L).map { offset ->
202+
val dayDate = weekStart.plusDays(offset)
203+
val tasks = tasksByDate[dayDate] ?: emptyList()
204+
205+
DayBlock(
206+
date = dayDate,
207+
tasks = tasks,
208+
isFirstOfMonth = dayDate.dayOfMonth == 1
210209
)
211-
)
210+
}.filter { it.date in startDate..endDate }
211+
212+
if (days.isNotEmpty()) {
213+
blocks.add(
214+
WeekBlock(
215+
weekKey = weekKeyFor(weekStart),
216+
label = buildWeekLabel(weekStart, weekStart.plusDays(6)),
217+
days = days
218+
)
219+
)
220+
}
212221
weekStart = weekStart.plusWeeks(1)
213222
}
214-
215223
return blocks
216224
}
217225

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.markel.flowstate.feature.calendar.components.taskslist
2+
3+
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.layout.Box
5+
import androidx.compose.foundation.layout.Row
6+
import androidx.compose.foundation.layout.Spacer
7+
import androidx.compose.foundation.layout.fillMaxWidth
8+
import androidx.compose.foundation.layout.padding
9+
import androidx.compose.foundation.layout.width
10+
import androidx.compose.foundation.shape.RoundedCornerShape
11+
import androidx.compose.material3.MaterialTheme
12+
import androidx.compose.material3.Text
13+
import androidx.compose.runtime.Composable
14+
import androidx.compose.ui.Alignment
15+
import androidx.compose.ui.Modifier
16+
import androidx.compose.ui.platform.LocalLocale
17+
import androidx.compose.ui.text.font.FontWeight
18+
import androidx.compose.ui.unit.dp
19+
import androidx.compose.ui.unit.sp
20+
import java.time.LocalDate
21+
import java.time.format.TextStyle
22+
23+
@Composable
24+
fun MonthBanner(date: LocalDate) {
25+
val monthName = date.month
26+
.getDisplayName(TextStyle.FULL, LocalLocale.current.platformLocale)
27+
.uppercase()
28+
29+
Box(
30+
modifier = Modifier
31+
.fillMaxWidth()
32+
.padding(horizontal = 16.dp, vertical = 20.dp)
33+
.background(
34+
color = MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 0.7f),
35+
shape = RoundedCornerShape(topStart = 28.dp, bottomEnd = 28.dp, topEnd = 4.dp, bottomStart = 4.dp)
36+
)
37+
.padding(16.dp)
38+
) {
39+
Row(verticalAlignment = Alignment.CenterVertically) {
40+
Text(
41+
text = monthName,
42+
style = MaterialTheme.typography.headlineSmall.copy(
43+
fontWeight = FontWeight.Black,
44+
letterSpacing = 2.sp
45+
),
46+
color = MaterialTheme.colorScheme.onSurface.copy(alpha=0.9f)
47+
)
48+
Spacer(modifier = Modifier.width(8.dp))
49+
Text(
50+
text = date.year.toString(),
51+
style = MaterialTheme.typography.bodyLarge,
52+
color = MaterialTheme.colorScheme.onSecondaryContainer
53+
)
54+
}
55+
}
56+
}

feature/calendar/src/main/res/drawable/radio_button_unchecked_24px.xml

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)