Skip to content

Commit 3c904b1

Browse files
Addressed PR comments
1 parent 7310469 commit 3c904b1

1 file changed

Lines changed: 97 additions & 38 deletions

File tree

app/src/main/java/com/cornellappdev/uplift/ui/screens/profile/WorkoutHistoryScreen.kt

Lines changed: 97 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.cornellappdev.uplift.ui.screens.profile
22

3+
import androidx.compose.animation.AnimatedContent
34
import androidx.compose.foundation.background
45
import androidx.compose.foundation.border
56
import androidx.compose.foundation.clickable
@@ -13,18 +14,22 @@ import androidx.compose.foundation.layout.fillMaxWidth
1314
import androidx.compose.foundation.layout.height
1415
import androidx.compose.foundation.layout.padding
1516
import androidx.compose.foundation.layout.size
17+
import androidx.compose.foundation.layout.statusBarsPadding
1618
import androidx.compose.foundation.layout.width
1719
import androidx.compose.foundation.lazy.LazyColumn
1820
import androidx.compose.foundation.lazy.grid.GridCells
1921
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
22+
import androidx.compose.foundation.lazy.items
2023
import androidx.compose.foundation.lazy.itemsIndexed
2124
import androidx.compose.foundation.shape.CircleShape
2225
import androidx.compose.material3.HorizontalDivider
2326
import androidx.compose.material3.Icon
27+
import androidx.compose.material3.IconButton
2428
import androidx.compose.material3.Text
2529
import androidx.compose.runtime.Composable
2630
import androidx.compose.runtime.collectAsState
2731
import androidx.compose.runtime.getValue
32+
import androidx.compose.runtime.mutableIntStateOf
2833
import androidx.compose.runtime.mutableStateOf
2934
import androidx.compose.runtime.remember
3035
import androidx.compose.runtime.setValue
@@ -63,7 +68,7 @@ fun WorkoutHistoryScreen(
6368
viewModel: ProfileViewModel = hiltViewModel(),
6469
onBack: () -> Unit
6570
) {
66-
val uiState by viewModel.uiStateFlow.collectAsState()
71+
val uiState = viewModel.collectUiStateValue()
6772
WorkoutHistoryScreenContent(uiState = uiState, onBack = onBack)
6873
}
6974

@@ -72,7 +77,7 @@ fun WorkoutHistoryScreenContent(
7277
uiState: ProfileUiState,
7378
onBack: () -> Unit
7479
) {
75-
var selectedTab by remember { mutableStateOf(0) }
80+
var selectedTab by remember { mutableIntStateOf(0) }
7681

7782
Column(
7883
modifier = Modifier
@@ -92,9 +97,11 @@ fun WorkoutHistoryScreenContent(
9297
EmptyHistorySection()
9398
}
9499
} else {
95-
when (selectedTab) {
96-
0 -> WorkoutHistoryCalendarView(historyItems = uiState.historyItems)
97-
1 -> WorkoutHistoryListView(historyItems = uiState.historyItems)
100+
AnimatedContent(targetState = selectedTab, label = "historyTabContent") { tab ->
101+
when (tab) {
102+
0 -> WorkoutHistoryCalendarView(historyItems = uiState.historyItems)
103+
1 -> WorkoutHistoryListView(historyItems = uiState.historyItems)
104+
}
98105
}
99106
}
100107
}
@@ -106,18 +113,23 @@ private fun WorkoutHistoryHeader(onBack: () -> Unit) {
106113
modifier = Modifier
107114
.fillMaxWidth()
108115
.background(LIGHT_GRAY)
116+
.statusBarsPadding()
109117
.padding(horizontal = 16.dp, vertical = 12.dp),
110118
verticalAlignment = Alignment.CenterVertically,
111119
horizontalArrangement = Arrangement.SpaceBetween
112120
) {
113-
Icon(
114-
painter = painterResource(id = R.drawable.ic_back_arrow),
115-
contentDescription = "Back",
116-
modifier = Modifier
117-
.size(24.dp)
118-
.clickable { onBack() },
119-
tint = PRIMARY_BLACK
120-
)
121+
IconButton(
122+
onClick = { onBack() },
123+
) {
124+
Icon(
125+
painter = painterResource(id = R.drawable.ic_back_arrow),
126+
contentDescription = "Back",
127+
modifier = Modifier
128+
.size(24.dp),
129+
tint = PRIMARY_BLACK
130+
)
131+
}
132+
121133
Text(
122134
text = "History",
123135
fontFamily = montserratFamily,
@@ -130,14 +142,42 @@ private fun WorkoutHistoryHeader(onBack: () -> Unit) {
130142
}
131143
}
132144

145+
private sealed class HistoryListItem {
146+
data class Header(val month: String) : HistoryListItem()
147+
data class Workout(
148+
val item: HistoryItem,
149+
val showDivider: Boolean
150+
) : HistoryListItem()
151+
data class SpacerItem(val month: String) : HistoryListItem()
152+
}
153+
133154
@Composable
134155
private fun WorkoutHistoryListView(historyItems: List<HistoryItem>) {
135156
val groupedItems = remember(historyItems) {
136-
historyItems.groupBy {
137-
val date = Instant.ofEpochMilli(it.timestamp)
138-
.atZone(ZoneId.systemDefault())
139-
.toLocalDate()
140-
date.format(DateTimeFormatter.ofPattern("MMMM yyyy", Locale.US))
157+
historyItems
158+
.sortedByDescending { it.timestamp }
159+
.groupBy { historyItem ->
160+
Instant.ofEpochMilli(historyItem.timestamp)
161+
.atZone(ZoneId.systemDefault())
162+
.toLocalDate()
163+
.format(DateTimeFormatter.ofPattern("MMMM yyyy", Locale.US))
164+
}
165+
}
166+
167+
val listItems = remember(groupedItems) {
168+
buildList {
169+
groupedItems.forEach { (month, items) ->
170+
add(HistoryListItem.Header(month))
171+
items.forEachIndexed { index, item ->
172+
add(
173+
HistoryListItem.Workout(
174+
item = item,
175+
showDivider = index < items.lastIndex
176+
)
177+
)
178+
}
179+
add(HistoryListItem.SpacerItem(month))
180+
}
141181
}
142182
}
143183

@@ -146,28 +186,46 @@ private fun WorkoutHistoryListView(historyItems: List<HistoryItem>) {
146186
.fillMaxSize()
147187
.padding(horizontal = 16.dp),
148188
) {
149-
item { Spacer(modifier = Modifier.height(8.dp)) }
189+
item(key = "top_spacer") {
190+
Spacer(modifier = Modifier.height(8.dp))
191+
}
150192

151-
groupedItems.forEach { (month, items) ->
152-
item {
153-
Text(
154-
text = month,
155-
fontFamily = montserratFamily,
156-
fontSize = 12.sp,
157-
fontWeight = FontWeight.Bold,
158-
color = Color.Black,
159-
modifier = Modifier.padding(top = 8.dp)
160-
)
193+
items(
194+
items = listItems,
195+
key = { listItem ->
196+
when (listItem) {
197+
is HistoryListItem.Header -> "header_${listItem.month}"
198+
is HistoryListItem.Workout -> "workout_${listItem.item.timestamp}"
199+
is HistoryListItem.SpacerItem -> "spacer_${listItem.month}"
200+
}
161201
}
162-
itemsIndexed(items) { index, item ->
163-
HistoryItemRow(historyItem = item)
164-
if (index < items.size - 1) {
165-
HorizontalDivider(color = GRAY01, thickness = 1.dp)
202+
) { listItem ->
203+
when (listItem) {
204+
is HistoryListItem.Header -> {
205+
Text(
206+
text = listItem.month,
207+
fontFamily = montserratFamily,
208+
fontSize = 12.sp,
209+
fontWeight = FontWeight.Bold,
210+
color = Color.Black,
211+
modifier = Modifier.padding(top = 8.dp)
212+
)
213+
}
214+
215+
is HistoryListItem.Workout -> {
216+
Column {
217+
HistoryItemRow(historyItem = listItem.item)
218+
if (listItem.showDivider) {
219+
HorizontalDivider(color = GRAY01, thickness = 1.dp)
220+
}
221+
}
222+
}
223+
224+
is HistoryListItem.SpacerItem -> {
225+
Spacer(modifier = Modifier.height(24.dp))
166226
}
167227
}
168-
item { Spacer(modifier = Modifier.height(24.dp)) }
169228
}
170-
171229
}
172230
}
173231

@@ -191,7 +249,10 @@ private fun WorkoutHistoryCalendarView(historyItems: List<HistoryItem>) {
191249
// Month Selector
192250
Row(
193251
modifier = Modifier.fillMaxWidth(),
194-
horizontalArrangement = Arrangement.Center,
252+
horizontalArrangement = Arrangement.spacedBy(
253+
24.dp,
254+
Alignment.CenterHorizontally
255+
),
195256
verticalAlignment = Alignment.CenterVertically
196257
) {
197258
Icon(
@@ -202,7 +263,6 @@ private fun WorkoutHistoryCalendarView(historyItems: List<HistoryItem>) {
202263
.clickable { currentMonth = currentMonth.minusMonths(1) },
203264
tint = PRIMARY_BLACK
204265
)
205-
Spacer(modifier = Modifier.width(24.dp))
206266
Text(
207267
text = currentMonth.format(DateTimeFormatter.ofPattern("MMM yyyy", Locale.US)),
208268
fontFamily = montserratFamily,
@@ -212,7 +272,6 @@ private fun WorkoutHistoryCalendarView(historyItems: List<HistoryItem>) {
212272
modifier = Modifier.width(100.dp),
213273
textAlign = TextAlign.Center
214274
)
215-
Spacer(modifier = Modifier.width(24.dp))
216275
Icon(
217276
painter = painterResource(id = R.drawable.ic_advance_month),
218277
contentDescription = "Next Month",

0 commit comments

Comments
 (0)