Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/#52 mypage followlist #65

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8369831
[feat] #52 add large, medium button
seohee0925 Jul 9, 2024
3e3da7f
[mod] #52 modify corner radius
seohee0925 Jul 9, 2024
506c415
[feat] #52 custom item
seohee0925 Jul 9, 2024
1083f43
[feat] #52 mypage followlist
seohee0925 Jul 10, 2024
e8a000e
[chore] #52 ktlint format
seohee0925 Jul 10, 2024
09d95f6
[mod] #52 delete preview
seohee0925 Jul 11, 2024
cbe8690
[mod] #52 delete import
seohee0925 Jul 11, 2024
2289fec
[mod] #52 resolve name conflict
seohee0925 Jul 11, 2024
b2ce561
[add] #55 add Icon
seohee0925 Jul 9, 2024
e9d9421
[mod] #55 change to vector asset
seohee0925 Jul 9, 2024
623b09e
[add] #56 add bubble graphic Typography
nagaeng Jul 9, 2024
9a84322
[chore] #56 ktlintformat (for add bubble graphic typo)
nagaeng Jul 9, 2024
d4289e2
add: add infinite scroll
lsakee Jul 9, 2024
f11075a
add: launched effect with lifecycle
lsakee Jul 9, 2024
b8da2b8
design: add component small text field
lsakee Jul 9, 2024
2e048ce
misc: kotlin format & reorder the parameters
lsakee Jul 9, 2024
0624c2d
design: add chip button component
lsakee Jul 9, 2024
49d6fd6
feat: custom click able
lsakee Jul 9, 2024
cf74710
feat: apply chip button custom clickable
lsakee Jul 9, 2024
5c341d6
[add] #47 add black alpha color
Sangwook123 Jul 10, 2024
bfa1dc7
[add] #47 add graphic asset resource
Sangwook123 Jul 10, 2024
d0c31dd
[feat] #47 feat recordy location badge
Sangwook123 Jul 10, 2024
865ebd2
[feat] #47 feat recordy dialog
Sangwook123 Jul 10, 2024
41a66eb
[feat] #47 recordy video thumbnail
Sangwook123 Jul 10, 2024
99ce8b3
[feat] #47 recordy snackbar
Sangwook123 Jul 10, 2024
7f491e3
[feat] #47 shadow icon
Sangwook123 Jul 10, 2024
640f724
[feat] #47 recordy video text
Sangwook123 Jul 10, 2024
2ae2b1f
[feat] #47 main navigation tab
Sangwook123 Jul 10, 2024
5934950
[feat] #47 video screen example code
Sangwook123 Jul 10, 2024
c19179a
[feat] #47 home screen example code
Sangwook123 Jul 10, 2024
8268879
[feat] #52 add large, medium button
seohee0925 Jul 9, 2024
bbd80b2
[chore] #52 ktlint format
seohee0925 Jul 10, 2024
5c83353
[mod] #52 resolve name conflict
seohee0925 Jul 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.record.designsystem.component.button

import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.record.designsystem.theme.RecordyTheme

@Composable
fun FollowButton(
isFollowing: Boolean,
onClick: () -> Unit,
) {
val colors = getButtonAndTextColor(isFollowing)

Button(
onClick = onClick,
colors = ButtonDefaults.buttonColors(
containerColor = colors.first,
),
shape = RoundedCornerShape(8.dp),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์š”๋Ÿฌํ•œ ๋ถ€๋ถ„๋“ค stalessํ•˜๊ฒŒ ํ˜ธ์ด์ŠคํŒ…ํ•ด๋„ ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!!!

contentPadding = PaddingValues(horizontal = 20.dp, vertical = 8.dp),
) {
Text(
text = if (isFollowing) "ํŒ”๋กœ์ž‰" else "ํŒ”๋กœ์šฐ",
color = colors.second,
style = RecordyTheme.typography.button2,
)
}
}

@Composable
fun getButtonAndTextColor(isFollowed: Boolean): Pair<Color, Color> {
return if (isFollowed) {
Pair(RecordyTheme.colors.gray08, RecordyTheme.colors.white)
} else {
Pair(RecordyTheme.colors.white, RecordyTheme.colors.gray08)
}
}
Comment on lines +38 to +44
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ํ…์ŠคํŠธ์™€ ๋ฒ„ํŠผ์˜ ์ปฌ๋Ÿฌ๋ฅผ ํ•˜๋‚˜๋กœ Pair ๋ฅผ ํ™œ์šฉํ•ด์„œ ๋ฐ›๋Š”๊ฑด ์ƒ๊ฐ ๋ชปํ•ด๋ดค๋Š”๋ฐ ์ž˜ ์‚ดํŽด๋ณด๊ณ  ๊ฐ€์š”


@Preview(showBackground = true)
@Composable
fun FollowButtonPreview() {
RecordyTheme {
FollowButton(
isFollowing = false,
onClick = {},
)
}
}
Original file line number Diff line number Diff line change
@@ -1,42 +1,45 @@
package com.record.designsystem.component.button

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.record.designsystem.theme.RecordyTheme

@Composable
fun RecordyButton(
text: String,
containerColor: Color = RecordyTheme.colors.main,
contentColor: Color = RecordyTheme.colors.gray09,
textStyle: TextStyle = RecordyTheme.typography.button1,
cornerShape: Dp = 12.dp,
enabled: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Button(
onClick = onClick,
enabled = enabled,

colors = ButtonDefaults.buttonColors(
containerColor = RecordyTheme.colors.main,
contentColor = RecordyTheme.colors.gray09,
containerColor = containerColor,
contentColor = contentColor,
disabledContainerColor = RecordyTheme.colors.gray08,
disabledContentColor = RecordyTheme.colors.gray04,
),

shape = RoundedCornerShape(12.dp),
shape = RoundedCornerShape(cornerShape),
modifier = modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
.fillMaxWidth(),
) {
Text(
text = text,
style = RecordyTheme.typography.button1,
style = textStyle,
)
}
}
8 changes: 8 additions & 0 deletions core/model/src/main/java/com/record/model/UserData.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.record.model

data class UserData(
val id: Int,
val profileImage: String,
val name: String,
val isFollowing: Boolean,
)
78 changes: 78 additions & 0 deletions feature/mypage/src/main/java/com/record/mypage/FollowScreen.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.record.mypage

import android.util.Log
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.record.designsystem.theme.RecordyTheme
import com.record.model.UserData
import kotlinx.coroutines.flow.collectLatest

@Composable
fun FollowRoute(
padding: PaddingValues,
modifier: Modifier = Modifier,
viewModel: FollowViewModel = hiltViewModel(),
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()

LaunchedEffect(Unit) {
viewModel.sideEffect.collectLatest { sideEffect ->
when (sideEffect) {
is FollowSideEffect.Following -> {
Log.d("FollowRoute", "$sideEffect")
}

is FollowSideEffect.UnFollowing -> {
Log.d("FollowRoute", "$sideEffect")
}
}
}
}

Box(
modifier = modifier
.fillMaxSize()
.background(RecordyTheme.colors.background)
.padding(padding),
) {
FollowScreen(
state = uiState,
onClick = { user -> viewModel.toggleFollow(user) },
)
}
}

@Composable
fun FollowScreen(state: FollowState, onClick: (UserData) -> Unit) {
LazyColumn(
modifier = Modifier.fillMaxSize(),
) {
items(state.userList) { user ->
UserDataContainer(
user = user,
onClick = onClick,
)
}
}
}

@Preview(showBackground = true)
@Composable
private fun PreviewFollowScreen() {
val sampleState = FollowState()
RecordyTheme {
FollowScreen(state = sampleState, onClick = {})
}
}
19 changes: 19 additions & 0 deletions feature/mypage/src/main/java/com/record/mypage/FollowState.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.record.mypage

import com.record.model.UserData
import com.record.ui.base.SideEffect
import com.record.ui.base.UiState

data class FollowState(
val userList: List<UserData> = listOf(
UserData(id = 1, profileImage = "https://via.placeholder.com/150", name = "John Doe", isFollowing = false),
UserData(id = 2, profileImage = "https://via.placeholder.com/150", name = "Jane Smith", isFollowing = false),
UserData(id = 3, profileImage = "https://via.placeholder.com/150", name = "Alice Johnson", isFollowing = false),
UserData(id = 4, profileImage = "https://via.placeholder.com/150", name = "Bob Brown", isFollowing = false),
),
) : UiState

sealed interface FollowSideEffect : SideEffect {
data object Following : FollowSideEffect
data object UnFollowing : FollowSideEffect
}
33 changes: 33 additions & 0 deletions feature/mypage/src/main/java/com/record/mypage/FollowViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.record.mypage

import androidx.lifecycle.viewModelScope
import com.record.model.UserData
import com.record.ui.base.BaseViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class FollowViewModel @Inject constructor() : BaseViewModel<FollowState, FollowSideEffect>(FollowState()) {

fun toggleFollow(user: UserData) {
intent {
val newList = uiState.value.userList.toMutableList()
val index = newList.indexOfFirst { it.id == user.id }
if (index >= 0) {
val updatedUser = newList[index].copy(isFollowing = !newList[index].isFollowing)
newList[index] = updatedUser
}

copy(userList = newList)
}

viewModelScope.launch {
if (user.isFollowing) {
postSideEffect(FollowSideEffect.Following)
} else {
postSideEffect(FollowSideEffect.UnFollowing)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.record.mypage

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImagePainter.State.Empty.painter
import coil.compose.rememberAsyncImagePainter
import com.record.designsystem.component.button.FollowButton
import com.record.designsystem.theme.RecordyTheme
import com.record.model.UserData

@Composable
fun UserDataContainer(user: UserData, onClick: (UserData) -> Unit) {
Row(
modifier = Modifier
.background(RecordyTheme.colors.background)
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
) {
Image(
painter = rememberAsyncImagePainter(user.profileImage),
contentDescription = null,
modifier = Modifier
.padding(vertical = 10.dp, horizontal = 16.dp)
.size(54.dp)
.clip(CircleShape),
)
Text(
text = user.name,
style = RecordyTheme.typography.body1M,
color = RecordyTheme.colors.white,
)
Spacer(modifier = Modifier.weight(1f))
FollowButton(
isFollowing = user.isFollowing,
onClick = { onClick(user) },
)
Spacer(modifier = Modifier.size(16.dp))
}
}

@Preview(showBackground = true)
@Composable
fun UserDataContainerPreview() {
val sampleUser = UserData(
id = 1,
profileImage = "https://via.placeholder.com/150",
name = "John Doe",
isFollowing = false,
)
RecordyTheme {
UserDataContainer(user = sampleUser, onClick = {})
}
}