Skip to content

Commit f4a3b4d

Browse files
addressed PR comments
1 parent db94495 commit f4a3b4d

1 file changed

Lines changed: 74 additions & 74 deletions

File tree

  • app/src/main/java/com/cornellappdev/uplift/ui/components/profile/achievements

app/src/main/java/com/cornellappdev/uplift/ui/components/profile/achievements/PRCards.kt

Lines changed: 74 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.cornellappdev.uplift.ui.components.profile.achievements
22

33
import androidx.compose.animation.core.Animatable
4+
import androidx.compose.animation.core.AnimationVector1D
45
import androidx.compose.animation.core.LinearOutSlowInEasing
56
import androidx.compose.animation.core.animateDpAsState
67
import androidx.compose.animation.core.animateFloatAsState
@@ -37,6 +38,7 @@ import androidx.compose.ui.geometry.Offset
3738
import androidx.compose.ui.graphics.Brush
3839
import androidx.compose.ui.graphics.Color
3940
import androidx.compose.ui.graphics.graphicsLayer
41+
import androidx.compose.ui.input.pointer.PointerInputScope
4042
import androidx.compose.ui.input.pointer.pointerInput
4143
import androidx.compose.ui.input.pointer.positionChange
4244
import androidx.compose.ui.input.pointer.util.VelocityTracker
@@ -62,6 +64,7 @@ import com.cornellappdev.uplift.util.YELLOW03
6264
import com.cornellappdev.uplift.util.YELLOW04
6365
import com.cornellappdev.uplift.util.YELLOW05
6466
import com.cornellappdev.uplift.util.montserratFamily
67+
import kotlinx.coroutines.CoroutineScope
6568
import kotlinx.coroutines.coroutineScope
6669
import kotlinx.coroutines.launch
6770
import java.lang.Float.min
@@ -80,33 +83,23 @@ data class PRCardData(
8083

8184
@Composable
8285
fun PRCards(
83-
prCardDataList: List<PRCardData>,
84-
onMoveToBack: (PRCardData) -> Unit
86+
prCardDataList: List<PRCardData>, onMoveToBack: (PRCardData) -> Unit
8587
) {
8688
Box(
87-
Modifier
88-
.fillMaxWidth(),
89-
contentAlignment = Alignment.CenterStart
89+
Modifier.fillMaxWidth(), contentAlignment = Alignment.CenterStart
9090
) {
9191
prCardDataList.forEachIndexed { idx, prCardData ->
9292
key(prCardData) {
9393
PRCard(
9494
order = idx,
9595
totalCount = prCardDataList.size,
96-
title = prCardData.title,
97-
weight = prCardData.weight,
98-
reps = prCardData.reps,
99-
backgroundGradient = prCardData.backgroundGradient,
100-
innerBorderGradient = prCardData.innerBorderGradient,
101-
titleColor = prCardData.titleColor,
102-
weightAndRepsColor = prCardData.weightAndRepsColor,
96+
prCardData = prCardData,
10397
onMoveToBack = {
10498
onMoveToBack(prCardData)
10599
},
106-
onUpdate = {
100+
onUpdatePressed = {
107101
/* TODO: Fill in with update function */
108-
}
109-
)
102+
})
110103
}
111104
}
112105
}
@@ -116,15 +109,9 @@ fun PRCards(
116109
fun PRCard(
117110
order: Int,
118111
totalCount: Int,
119-
title: String,
120-
weight: Int,
121-
reps: Int,
122-
backgroundGradient: Brush,
123-
innerBorderGradient: Brush,
124-
titleColor: Color,
125-
weightAndRepsColor: Color,
112+
prCardData: PRCardData,
126113
onMoveToBack: () -> Unit,
127-
onUpdate: () -> Unit
114+
onUpdatePressed: () -> Unit
128115
) {
129116
val animatedScale by animateFloatAsState(
130117
targetValue = 1f - (totalCount - order) * 0.05f,
@@ -140,14 +127,14 @@ fun PRCard(
140127
scaleX = animatedScale
141128
scaleY = animatedScale
142129
}
143-
.swipeToRight { onMoveToBack() }
130+
.onSwipeToRight { onMoveToBack() }
144131
.height(311.dp)
145132
.width(229.dp)
146133
.shadow(
147134
elevation = 6.dp,
148135
shape = RoundedCornerShape(22.dp),
149136
)
150-
.background(backgroundGradient, RoundedCornerShape(22.dp))
137+
.background(prCardData.backgroundGradient, RoundedCornerShape(22.dp))
151138
.padding(6.dp)
152139

153140
) {
@@ -157,24 +144,23 @@ fun PRCard(
157144
.height(298.dp)
158145
.border(
159146
width = 1.4.dp,
160-
brush = innerBorderGradient,
147+
brush = prCardData.innerBorderGradient,
161148
shape = RoundedCornerShape(16.5.dp)
162149
)
163150
.padding(vertical = 39.dp)
164151
) {
165-
PRCardContent(title, titleColor, weight, reps, weightAndRepsColor, onUpdate)
152+
PRCardContent(
153+
prCardData,
154+
onUpdatePressed
155+
)
166156
}
167157
}
168158
}
169159

170160
@Composable
171161
private fun PRCardContent(
172-
title: String,
173-
titleColor: Color,
174-
weight: Int,
175-
reps: Int,
176-
weightAndRepsColor: Color,
177-
onUpdate: () -> Unit
162+
prCardData: PRCardData,
163+
onUpdatePressed: () -> Unit
178164
) {
179165
Column(
180166
modifier = Modifier
@@ -189,30 +175,30 @@ private fun PRCardContent(
189175
)
190176
Spacer(modifier = Modifier.height(11.dp))
191177
Text(
192-
text = title,
193-
color = titleColor,
178+
text = prCardData.title,
179+
color = prCardData.titleColor,
194180
fontFamily = montserratFamily,
195181
fontSize = 22.sp,
196182
fontWeight = FontWeight.Bold,
197183
)
198184
Spacer(modifier = Modifier.height(16.dp))
199185
Text(
200-
text = "$weight lb / $reps reps",
201-
color = weightAndRepsColor,
186+
text = "${prCardData.weight} lb / ${prCardData.reps} reps",
187+
color = prCardData.weightAndRepsColor,
202188
fontFamily = montserratFamily,
203189
fontSize = 16.sp,
204190
fontWeight = FontWeight.Medium,
205191
)
206192
Spacer(modifier = Modifier.weight(1f))
207193
UpdateButton(
208-
onUpdate = onUpdate
194+
onUpdatePressed = onUpdatePressed
209195
)
210196
}
211197
}
212198

213199
@Composable
214200
private fun UpdateButton(
215-
onUpdate: () -> Unit
201+
onUpdatePressed: () -> Unit
216202
) {
217203
val yellowBorderGradient = Brush.linearGradient(
218204
colors = listOf(LIGHT_YELLOW, PRIMARY_YELLOW)
@@ -223,16 +209,13 @@ private fun UpdateButton(
223209
.width(82.dp)
224210
.height(32.dp)
225211
.background(
226-
color = PRIMARY_BLACK,
227-
shape = RoundedCornerShape(30.dp)
212+
color = PRIMARY_BLACK, shape = RoundedCornerShape(30.dp)
228213
)
229214
.border(
230-
width = 1.4.dp,
231-
brush = yellowBorderGradient,
232-
shape = RoundedCornerShape(30.dp)
215+
width = 1.4.dp, brush = yellowBorderGradient, shape = RoundedCornerShape(30.dp)
233216
)
234217
.clickable(
235-
onClick = onUpdate,
218+
onClick = onUpdatePressed,
236219
)
237220
) {
238221
Text(
@@ -245,7 +228,7 @@ private fun UpdateButton(
245228
}
246229
}
247230

248-
private fun Modifier.swipeToRight(
231+
private fun Modifier.onSwipeToRight(
249232
onMoveToBack: () -> Unit
250233
): Modifier = composed {
251234
val offsetX = remember { Animatable(0f) }
@@ -274,35 +257,54 @@ private fun Modifier.swipeToRight(
274257
if (targetOffsetX.absoluteValue <= size.width) {
275258
launch { offsetX.animateTo(targetValue = 0f, initialVelocity = velocity) }
276259
} else {
277-
val boomerangDuration = 600
278-
val maxDistanceToFling =
279-
(size.width * 4).toFloat()
280-
val distanceToFling = min(
281-
targetOffsetX.absoluteValue + size.width, maxDistanceToFling
260+
onAnimateBoomerang(
261+
this@pointerInput,
262+
targetOffsetX,
263+
this@coroutineScope,
264+
offsetX,
265+
velocity,
266+
clearedHurdle,
267+
setClearedHurdle = { clearedHurdle = it },
268+
onMoveToBack
282269
)
283-
284-
launch {
285-
offsetX.animateTo(
286-
targetValue = 0f,
287-
initialVelocity = velocity,
288-
animationSpec = keyframes {
289-
durationMillis = boomerangDuration
290-
distanceToFling at (boomerangDuration / 2) using LinearOutSlowInEasing
291-
40f at boomerangDuration - 70
292-
}
293-
) {
294-
if (value >= size.width * 2 && !clearedHurdle) {
295-
onMoveToBack()
296-
clearedHurdle = true
297-
}
298-
}
299-
clearedHurdle = false
300-
}
301270
}
302271
}
303272
}
273+
}.offset { IntOffset(offsetX.value.roundToInt(), 0) }
274+
}
275+
276+
private fun onAnimateBoomerang(
277+
pointerInputScope: PointerInputScope,
278+
targetOffsetX: Float,
279+
coroutineScope: CoroutineScope,
280+
offsetX: Animatable<Float, AnimationVector1D>,
281+
velocity: Float,
282+
clearedHurdle: Boolean,
283+
setClearedHurdle: (Boolean) -> Unit,
284+
onMoveToBack: () -> Unit
285+
) {
286+
val boomerangDuration = 600
287+
val maxDistanceToFling = (pointerInputScope.size.width * 4).toFloat()
288+
val distanceToFling = min(
289+
targetOffsetX.absoluteValue + pointerInputScope.size.width, maxDistanceToFling
290+
)
291+
val boomerangAnimationOffset = 70
292+
coroutineScope.launch {
293+
offsetX.animateTo(
294+
targetValue = 0f,
295+
initialVelocity = velocity,
296+
animationSpec = keyframes {
297+
durationMillis = boomerangDuration
298+
distanceToFling at (boomerangDuration / 2) using LinearOutSlowInEasing
299+
40f at boomerangDuration - boomerangAnimationOffset
300+
}) {
301+
if (value >= pointerInputScope.size.width * 2 && !clearedHurdle) {
302+
onMoveToBack()
303+
setClearedHurdle(true)
304+
}
305+
}
306+
setClearedHurdle(false)
304307
}
305-
.offset { IntOffset(offsetX.value.roundToInt(), 0) }
306308
}
307309

308310
@Preview
@@ -357,11 +359,9 @@ private fun PRCardsPreview() {
357359
)
358360
}
359361
PRCards(
360-
prCardDataList = prCardDataList,
361-
onMoveToBack = { prCardData ->
362+
prCardDataList = prCardDataList, onMoveToBack = { prCardData ->
362363
prCardDataList = listOf(prCardData) + (prCardDataList - prCardData)
363-
}
364-
)
364+
})
365365
}
366366

367367

0 commit comments

Comments
 (0)