Skip to content

Commit 979d98a

Browse files
committed
refactor: Ajustando visualização de contagem de likes
1 parent 55c4300 commit 979d98a

File tree

11 files changed

+193
-62
lines changed

11 files changed

+193
-62
lines changed

app/src/main/java/com/paradoxo/threadscompose/model/Comment.kt

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

app/src/main/java/com/paradoxo/threadscompose/model/Post.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ data class Post(
77
val description: String = "",
88
val date: Long = 0L,
99
val medias: List<String> = emptyList(),
10-
val likes: List<String> = emptyList(),
10+
val likes: List<Like> = emptyList(),
1111
val comments: List<Comment> = emptyList()
1212
)
13+
14+
data class Like(
15+
val id: String = "",
16+
val profilePicAuthor: String = "",
17+
)
18+
19+
data class Comment(
20+
val id: String = "",
21+
val profilePicAuthor: String = "",
22+
)

app/src/main/java/com/paradoxo/threadscompose/sampleData/SampleData.kt

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.paradoxo.threadscompose.sampleData
22

33
import com.paradoxo.threadscompose.R
44
import com.paradoxo.threadscompose.model.Comment
5+
import com.paradoxo.threadscompose.model.Like
56
import com.paradoxo.threadscompose.model.Notification
67
import com.paradoxo.threadscompose.model.NotificationTypeEnum
78
import com.paradoxo.threadscompose.model.Post
@@ -15,6 +16,7 @@ class SampleData {
1516
val notifications = mutableListOf<Notification>()
1617
val posts = mutableListOf<Post>()
1718
val userAccounts = mutableListOf<UserAccount>()
19+
private val comments = mutableListOf<Comment>()
1820

1921
private val descriptions = listOf(
2022
"Viver o momento é a verdadeira essência da vida!",
@@ -40,7 +42,7 @@ class SampleData {
4042
"Buscando a magia em cada dia.",
4143
"Vivendo a vida ao máximo!"
4244
)
43-
private val images = listOf(
45+
val images = listOf(
4446
"https://raw.githubusercontent.com/git-jr/sample-files/7bc859dfa8a6241fa9c0d723ba6e7517bdfedd50/profile%20pics/profile_pic_emoji_1.png",
4547
"https://raw.githubusercontent.com/git-jr/sample-files/7bc859dfa8a6241fa9c0d723ba6e7517bdfedd50/profile%20pics/profile_pic_emoji_2.png",
4648
"https://raw.githubusercontent.com/git-jr/sample-files/7bc859dfa8a6241fa9c0d723ba6e7517bdfedd50/profile%20pics/profile_pic_emoji_3.png",
@@ -73,7 +75,7 @@ class SampleData {
7375
description = descriptions[i - 1],
7476
date = getCurrentTime(),
7577
medias = if (Random.nextBoolean()) images.shuffled() else listOf(),
76-
likes = generateListRandomIdStrings(),
78+
likes = generateListSamplesLikes(),
7779
comments = generateSampleComments()
7880
)
7981
posts.add(post)
@@ -99,6 +101,13 @@ class SampleData {
99101
isFollowing = Random.nextBoolean(),
100102
)
101103
)
104+
105+
comments.add(
106+
Comment(
107+
id = UUID.randomUUID().toString(),
108+
profilePicAuthor = images.random(),
109+
)
110+
)
102111
}
103112

104113
}
@@ -128,6 +137,21 @@ class SampleData {
128137
return comments
129138
}
130139

140+
private fun generateListSamplesLikes(): List<Like> {
141+
if (Random.nextBoolean()) return emptyList()
142+
143+
val likes = mutableListOf<Like>()
144+
repeat(Random.nextInt(0, 10)) {
145+
likes.add(
146+
Like(
147+
id = it.toString(),
148+
profilePicAuthor = images.random(),
149+
)
150+
)
151+
}
152+
return likes
153+
}
154+
131155
fun generateSampleInvitedUser(): UserAccount {
132156
return UserAccount(
133157
id = UUID.randomUUID().toString(),

app/src/main/java/com/paradoxo/threadscompose/ui/Components.kt

Lines changed: 89 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.paradoxo.threadscompose.ui
22

3+
import androidx.compose.animation.core.Spring
4+
import androidx.compose.animation.core.animateFloatAsState
5+
import androidx.compose.animation.core.spring
36
import androidx.compose.foundation.border
4-
import androidx.compose.foundation.clickable
57
import androidx.compose.foundation.layout.Arrangement
68
import androidx.compose.foundation.layout.Box
79
import androidx.compose.foundation.layout.Column
@@ -26,9 +28,11 @@ import androidx.compose.material3.Icon
2628
import androidx.compose.material3.MaterialTheme
2729
import androidx.compose.material3.Text
2830
import androidx.compose.runtime.Composable
31+
import androidx.compose.runtime.getValue
2932
import androidx.compose.ui.Alignment
3033
import androidx.compose.ui.Modifier
3134
import androidx.compose.ui.draw.clip
35+
import androidx.compose.ui.draw.scale
3236
import androidx.compose.ui.graphics.Color
3337
import androidx.compose.ui.layout.ContentScale
3438
import androidx.compose.ui.platform.LocalContext
@@ -43,6 +47,7 @@ import com.paradoxo.threadscompose.model.Post
4347
import com.paradoxo.threadscompose.sampleData.SampleData
4448
import com.paradoxo.threadscompose.utils.formatTimeElapsed
4549
import com.paradoxo.threadscompose.utils.getCurrentTime
50+
import com.paradoxo.threadscompose.utils.noRippleClickable
4651

4752
@Composable
4853
fun PostItem(
@@ -171,13 +176,11 @@ fun PostItem(
171176
Row(
172177
Modifier.padding(vertical = 8.dp),
173178
) {
174-
Icon(
175-
painterResource(id = R.drawable.ic_heart),
176-
contentDescription = "like",
177-
modifier = Modifier.clickable {
178-
onLikeClick(post.id)
179-
},
180-
tint = if (isLiked) Color.Red else Color.Black
179+
180+
LikeButton(
181+
isLiked = isLiked,
182+
onLikeClick = onLikeClick,
183+
postId = post.id
181184
)
182185

183186
Spacer(modifier = Modifier.width(10.dp))
@@ -200,7 +203,7 @@ fun PostItem(
200203
}
201204
}
202205
}
203-
if (commentsSize > 0) {
206+
if (commentsSize > 0 || likesSize > 0) {
204207
Row(
205208
Modifier
206209
.fillMaxWidth(),
@@ -214,48 +217,63 @@ fun PostItem(
214217
horizontalAlignment = Alignment.CenterHorizontally,
215218
verticalArrangement = Arrangement.Center
216219
) {
220+
if (commentsSize > 0) {
221+
when (post.comments.size) {
222+
1 -> {
223+
ContainerOneProfilePic(post.comments.first().profilePicAuthor)
224+
}
217225

218-
when (post.comments.size) {
219-
1 -> {
220-
ContainerOneProfilePic(
221-
post.comments.first().profilePicAuthor
222-
)
223-
}
226+
2 -> {
227+
val profilePics = post.comments.take(2).map { it.profilePicAuthor }
228+
if (profilePics.distinct().size == 1) {
229+
ContainerOneProfilePic(profilePics.first())
230+
} else {
231+
ContainerTwoProfilePics(profilePics[0], profilePics[1])
232+
}
233+
}
224234

225-
2 -> {
226-
val firstProfilePic = post.comments.first().profilePicAuthor
227-
val secondProfilePic = post.comments[1].profilePicAuthor
228-
if (firstProfilePic == secondProfilePic) {
229-
ContainerOneProfilePic(
230-
firstProfilePic
231-
)
232-
} else {
233-
ContainerTwoProfilePics(
234-
firstProfilePic,
235-
secondProfilePic
236-
)
235+
else -> {
236+
val profilePics = post.comments.take(3).map { it.profilePicAuthor }
237+
if (profilePics.distinct().size == 1) {
238+
ContainerOneProfilePic(profilePics.first())
239+
} else {
240+
ContainerMoreTwoProfilePics(
241+
profilePics[0],
242+
profilePics[1],
243+
profilePics[2]
244+
)
245+
}
237246
}
238247
}
248+
} else {
249+
when (post.likes.size) {
250+
1 -> {
251+
ContainerOneProfilePic(post.likes.first().profilePicAuthor)
252+
}
239253

240-
else -> {
241-
val firstProfilePic = post.comments.first().profilePicAuthor
242-
val secondProfilePic = post.comments[1].profilePicAuthor
243-
val thirdProfilePic = post.comments[2].profilePicAuthor
244-
if (secondProfilePic == thirdProfilePic && firstProfilePic == secondProfilePic) {
245-
ContainerOneProfilePic(
246-
post.comments.first().profilePicAuthor
247-
)
248-
} else {
249-
ContainerMoreTwoProfilePics(
250-
firstProfilePic,
251-
secondProfilePic,
252-
thirdProfilePic
253-
)
254+
2 -> {
255+
val profilePics = post.likes.take(2).map { it.profilePicAuthor }
256+
if (profilePics.distinct().size == 1) {
257+
ContainerOneProfilePic(profilePics.first())
258+
} else {
259+
ContainerTwoProfilePics(profilePics[0], profilePics[1])
260+
}
254261
}
255262

263+
else -> {
264+
val profilePics = post.likes.take(3).map { it.profilePicAuthor }
265+
if (profilePics.distinct().size == 1) {
266+
ContainerOneProfilePic(profilePics.first())
267+
} else {
268+
ContainerMoreTwoProfilePics(
269+
profilePics[0],
270+
profilePics[1],
271+
profilePics[2]
272+
)
273+
}
274+
}
256275
}
257276
}
258-
259277
}
260278
Row(
261279
Modifier
@@ -286,6 +304,7 @@ fun PostItem(
286304
color = Color.Gray.copy(alpha = 0.8f)
287305
)
288306
)
307+
Spacer(modifier = Modifier.width(4.dp))
289308
}
290309
}
291310
}
@@ -433,11 +452,38 @@ private fun ContainerMoreTwoProfilePics(
433452
}
434453
}
435454

455+
456+
@Composable
457+
fun LikeButton(
458+
isLiked: Boolean, onLikeClick: (String) -> Unit,
459+
postId: String
460+
) {
461+
val scale: Float by animateFloatAsState(
462+
targetValue = if (isLiked) 1.1f else 1f,
463+
animationSpec = spring(
464+
dampingRatio = Spring.DampingRatioHighBouncy,
465+
stiffness = Spring.StiffnessMedium
466+
), label = ""
467+
)
468+
469+
val resourceId = if (isLiked) R.drawable.ic_heart else R.drawable.ic_heart_outlined
470+
Icon(
471+
painter = painterResource(id = resourceId),
472+
contentDescription = "like",
473+
modifier = Modifier
474+
.noRippleClickable {
475+
onLikeClick(postId)
476+
}
477+
.scale(scale),
478+
tint = if (isLiked) Color.Red else Color.Black
479+
)
480+
}
481+
436482
@Preview(showBackground = true)
437483
@Composable
438484
private fun PostItemPreview() {
439485
PostItem(
440486
post = SampleData().posts.first(),
441487
isLiked = true
442488
)
443-
}
489+
}

app/src/main/java/com/paradoxo/threadscompose/ui/feed/FeedScreen.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ import kotlinx.coroutines.launch
4242
fun FeedScreen(
4343
modifier: Modifier = Modifier,
4444
posts: List<Post> = emptyList(),
45+
onLikeClick: (Post) -> Unit = {},
46+
idCurrentUserProfile: String = "",
4547
) {
4648
LazyColumn(
4749
modifier = modifier
@@ -57,12 +59,13 @@ fun FeedScreen(
5759
key = { post -> post.id }
5860
) { post ->
5961
val isLiked = rememberSaveable {
60-
mutableStateOf(post.likes.contains(post.userAccount.id))
62+
mutableStateOf(post.likes.any { it.id == idCurrentUserProfile })
6163
}
6264
PostItem(
6365
post,
6466
isLiked.value,
6567
onLikeClick = {
68+
onLikeClick(post)
6669
isLiked.value = !isLiked.value
6770
}
6871
)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.paradoxo.threadscompose.ui.feed
22

33
import com.paradoxo.threadscompose.model.Post
4+
import com.paradoxo.threadscompose.model.UserAccount
45

56
data class FeedScreenState(
67
var posts: List<Post> = emptyList(),
8+
val currentUserProfile: UserAccount = UserAccount(),
79
)

app/src/main/java/com/paradoxo/threadscompose/ui/feed/FeedViewModel.kt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package com.paradoxo.threadscompose.ui.feed
22

33
import androidx.lifecycle.ViewModel
4+
import com.google.firebase.auth.ktx.auth
5+
import com.google.firebase.ktx.Firebase
6+
import com.paradoxo.threadscompose.model.Like
7+
import com.paradoxo.threadscompose.model.Post
8+
import com.paradoxo.threadscompose.model.UserAccount
49
import com.paradoxo.threadscompose.network.firebase.PostFirestore
510
import com.paradoxo.threadscompose.sampleData.SampleData
611
import kotlinx.coroutines.flow.MutableStateFlow
@@ -22,5 +27,48 @@ internal class FeedViewModel : ViewModel() {
2227
_uiState.value = _uiState.value.copy(posts = SampleData().posts)
2328
}
2429
)
30+
31+
_uiState.value = _uiState.value.copy(
32+
currentUserProfile = UserAccount(
33+
id = Firebase.auth.currentUser?.uid ?: "",
34+
userName = Firebase.auth.currentUser?.displayName ?: "",
35+
imageProfileUrl = Firebase.auth.currentUser?.photoUrl.toString()
36+
)
37+
)
38+
}
39+
40+
fun likePost(it: Post) {
41+
42+
if (it.likes.any { like -> like.id == _uiState.value.currentUserProfile.id }) {
43+
_uiState.value = _uiState.value.copy(posts = _uiState.value.posts.map { post ->
44+
if (post.id == it.id) {
45+
post.copy(
46+
likes = post.likes.toMutableList().apply {
47+
removeIf { like -> like.id == _uiState.value.currentUserProfile.id }
48+
}
49+
)
50+
} else {
51+
post
52+
}
53+
})
54+
return
55+
}
56+
57+
_uiState.value = _uiState.value.copy(posts = _uiState.value.posts.map { post ->
58+
if (post.id == it.id) {
59+
post.copy(
60+
likes = post.likes.toMutableList().apply {
61+
add(
62+
Like(
63+
id = _uiState.value.currentUserProfile.id,
64+
profilePicAuthor = _uiState.value.currentUserProfile.imageProfileUrl
65+
)
66+
)
67+
}
68+
)
69+
} else {
70+
post
71+
}
72+
})
2573
}
2674
}

0 commit comments

Comments
 (0)