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

TOP-104 회원가입 완료 화면 구현 #127

Merged
merged 3 commits into from
Sep 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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,74 @@
package com.example.compose_ui.component.card

import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.rotate
import androidx.compose.ui.unit.dp

// https://proandroiddev.com/animate-borders-in-jetpack-compose-ca359deed7d5
@Composable
fun CardWithAnimatedBorder(
modifier: Modifier = Modifier,
onCardClick: () -> Unit = {},
borderColors: List<Color> = emptyList(),
content: @Composable () -> Unit
) {
val infiniteTransition = rememberInfiniteTransition(label = "")
val angle by
infiniteTransition.animateFloat(
initialValue = 0f,
targetValue = 360f,
animationSpec =
infiniteRepeatable(
animation = tween(1000, easing = LinearEasing),
repeatMode = RepeatMode.Restart
),
label = ""
)

val brush = if (borderColors.isNotEmpty()) {
Brush.sweepGradient(borderColors)
} else {
Brush.sweepGradient(listOf(Color.Gray, Color.White))
}

Surface(
modifier = modifier.clickable { onCardClick() },
shape = RoundedCornerShape(32.dp)
) {
Surface(
modifier = Modifier
.clipToBounds()
.padding(4.dp)
.drawWithContent {
rotate(angle) {
drawCircle(
brush = brush,
radius = size.width,
blendMode = BlendMode.SrcIn,
)
}
drawContent()
},
shape = RoundedCornerShape(32.dp)
) {
content()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ class SignupCompleteActivity : AppCompatActivity() {
val state by viewModel.uiStateFlow.collectAsState()
SignupCompleteScreen(
loading = state.loading,
btnEnable = !state.profileImage.isNullOrBlank() && state.error != null && !state.loading,
profileImage = state.profileImage,
onComplete = viewModel::onCompleteEvent
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,134 @@
package tht.feature.signin.signup.signupcomplete.composable

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Icon
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil.compose.AsyncImage
import coil.request.ImageRequest
import coil.size.Size
import com.example.compose_ui.component.card.CardWithAnimatedBorder
import com.example.compose_ui.component.progress.ThtCircularProgress
import com.example.compose_ui.component.text.ThtText
import tht.core.ui.R
import tht.core.ui.extension.showToast
import tht.feature.signin.ui.SignupLargeButton

@Composable
internal fun SignupCompleteScreen(
loading: Boolean,
btnEnable: Boolean,
profileImage: String?,
onComplete: () -> Unit,
modifier: Modifier = Modifier,
error: Throwable? = null
) {
val context = LocalContext.current
Box {
Column(
modifier = modifier
.background(colorResource(id = R.color.black_161616))
.padding(horizontal = 22.dp)
) {
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.Center
) {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
ThtText(
text = "환영해요",
textSize = 24.sp,
fontWeight = FontWeight.Bold,
lineHeight = 33.6.sp,
color = colorResource(R.color.white_f9fafa)
)
Icon(
modifier = Modifier.size(34.dp),
painter = painterResource(
tht.feature.signin.R.drawable.ic_topic
),
tint = colorResource(R.color.yellow_f9cc2e),
contentDescription = "ic_topic"
)
}
ThtText(
modifier = Modifier.fillMaxWidth(),
text = "모든 준비가 끝났어요",
textSize = 24.sp,
fontWeight = FontWeight.Bold,
lineHeight = 33.6.sp,
color = colorResource(R.color.white_f9fafa)
)
Spacer(modifier = Modifier.height(16.dp))
ThtText(
modifier = Modifier.fillMaxWidth(),
text = "폴링에 한번 빠져보시겠어요?",
textSize = 17.sp,
fontWeight = FontWeight.Normal,
lineHeight = 22.1.sp,
color = colorResource(R.color.gray_8d8d8d)
)
}
CardWithAnimatedBorder(
modifier = Modifier
.size(182.dp)
.align(Alignment.CenterHorizontally),
borderColors = listOf(Color(0xFFF9CC2E), Color(0xFFFF7539))
) {
Box(
modifier = Modifier
.background(color = colorResource(R.color.black_161616))
.padding(11.dp)
) {
val model = remember(profileImage) {
ImageRequest.Builder(context)
.data(profileImage)
.size(Size.ORIGINAL)
.crossfade(true)
.build()
}
AsyncImage(
modifier = modifier
.fillMaxSize()
.clip(RoundedCornerShape(20.dp)),
model = model,
contentDescription = "profile_image",
contentScale = ContentScale.Crop
)
}
}
Spacer(modifier = Modifier.weight(1f))
//TODO: ProfileImage
SignupLargeButton(
onClick = onComplete,
text = stringResource(id = tht.feature.signin.R.string.yes),
enable = btnEnable
enable = !loading
)
Spacer(modifier = Modifier.height(22.dp))
}
Expand All @@ -46,7 +138,9 @@ internal fun SignupCompleteScreen(
visible = loading
)
}
if (error != null) {
// error dialog
LaunchedEffect(error) {
if (error != null) {
context.showToast(error.message ?: error.toString())
}
}
}
61 changes: 61 additions & 0 deletions feature/signin/src/main/res/drawable/ic_topic.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="34dp"
android:height="34dp"
android:viewportWidth="34"
android:viewportHeight="34">
<path
android:pathData="M26.475,26.018C29.386,23.108 27.329,16.332 21.881,10.884C16.434,5.437 9.658,3.38 6.748,6.29C5.306,7.732 5.431,10.759 6.414,13.793C6.43,13.842 6.476,13.875 6.528,13.875C6.607,13.875 6.664,13.8 6.644,13.723C6.01,11.359 5.906,8.922 6.907,7.902C9.026,5.744 15.136,7.071 19.875,11.724C24.615,16.376 26.761,22.119 24.643,24.277C23.034,25.917 19.498,25.336 16.347,24.072C15.995,23.931 15.604,24.185 15.604,24.565C15.604,24.746 15.697,24.914 15.851,25.008C20.105,27.612 24.335,28.158 26.475,26.018Z"
android:fillColor="#F9CC2E"
android:fillType="evenOdd"/>
<path
android:pathData="M12.707,15.909C12.691,15.157 13.704,14.902 14.046,15.572L16.011,19.42C16.11,19.615 16.293,19.752 16.507,19.794L20.417,20.551C21.007,20.665 21.196,21.415 20.731,21.795L17.644,24.313C17.475,24.451 17.379,24.659 17.384,24.877L17.475,29.197C17.491,29.949 16.478,30.204 16.136,29.534L14.171,25.685C14.072,25.491 13.889,25.353 13.675,25.312L9.765,24.555C9.175,24.44 8.986,23.69 9.452,23.31L12.538,20.792C12.707,20.655 12.803,20.447 12.798,20.229L12.707,15.909Z"
android:fillColor="#F9CC2E"/>
<path
android:pathData="M26.475,26.018C29.386,23.108 27.329,16.332 21.881,10.884C16.434,5.437 9.658,3.38 6.748,6.29C5.321,7.717 5.429,10.695 6.383,13.698C6.417,13.803 6.515,13.874 6.626,13.874C6.797,13.874 6.921,13.708 6.874,13.543C6.222,11.214 6.093,8.732 7.096,7.71C9.126,5.644 14.905,6.843 19.354,11.211C23.803,15.579 25.784,21.006 23.755,23.072C22.4,24.453 19.65,24.22 16.983,23.349C16.317,23.131 15.604,23.61 15.604,24.311C15.604,24.649 15.777,24.966 16.068,25.139C20.249,27.63 24.372,28.122 26.475,26.018Z"
android:fillColor="#F9CC2E"
android:fillAlpha="0.54"
android:fillType="evenOdd"/>
<group>
<clip-path
android:pathData="M26.475,26.018C29.386,23.108 27.329,16.332 21.881,10.884C16.434,5.437 9.658,3.38 6.748,6.29C5.321,7.717 5.429,10.695 6.383,13.698C6.417,13.803 6.515,13.874 6.626,13.874C6.797,13.874 6.921,13.708 6.874,13.543C6.222,11.214 6.093,8.732 7.096,7.71C9.126,5.644 14.905,6.843 19.354,11.211C23.803,15.579 25.784,21.006 23.755,23.072C22.4,24.453 19.65,24.22 16.983,23.349C16.317,23.131 15.604,23.61 15.604,24.311C15.604,24.649 15.777,24.966 16.068,25.139C20.249,27.63 24.372,28.122 26.475,26.018Z"
android:fillType="evenOdd"/>
<path
android:pathData="M21.881,10.884L22.031,10.734L21.881,10.884ZM6.748,6.29L6.898,6.441L6.748,6.29ZM7.096,7.71L6.945,7.561L7.096,7.71ZM19.354,11.211L19.205,11.363L19.354,11.211ZM23.755,23.072L23.604,22.923L23.604,22.923L23.755,23.072ZM16.068,25.139L16.177,24.957L16.068,25.139ZM6.874,13.543L7.079,13.486L6.874,13.543ZM16.983,23.349L16.917,23.551L16.983,23.349ZM6.383,13.698L6.181,13.762L6.383,13.698ZM21.731,11.035C24.435,13.739 26.29,16.765 27.109,19.464C27.931,22.173 27.698,24.495 26.325,25.868L26.625,26.168C28.163,24.631 28.356,22.109 27.516,19.341C26.672,16.563 24.775,13.478 22.031,10.734L21.731,11.035ZM6.898,6.441C8.271,5.068 10.592,4.834 13.301,5.656C16,6.476 19.027,8.331 21.731,11.035L22.031,10.734C19.288,7.991 16.203,6.093 13.425,5.25C10.656,4.409 8.135,4.603 6.597,6.14L6.898,6.441ZM6.586,13.633C6.113,12.147 5.854,10.676 5.885,9.408C5.916,8.137 6.239,7.099 6.898,6.441L6.597,6.14C5.83,6.908 5.493,8.073 5.46,9.398C5.427,10.726 5.699,12.246 6.181,13.762L6.586,13.633ZM6.945,7.561C6.383,8.132 6.164,9.079 6.152,10.134C6.14,11.199 6.34,12.422 6.67,13.6L7.079,13.486C6.757,12.334 6.566,11.152 6.577,10.139C6.588,9.115 6.805,8.309 7.248,7.859L6.945,7.561ZM19.503,11.06C17.254,8.852 14.665,7.44 12.371,6.842C10.096,6.249 8.042,6.444 6.945,7.561L7.248,7.859C8.18,6.91 10.031,6.671 12.264,7.253C14.48,7.831 17.005,9.203 19.205,11.363L19.503,11.06ZM23.907,23.221C24.461,22.656 24.73,21.873 24.761,20.969C24.793,20.065 24.588,19.029 24.183,17.931C23.373,15.736 21.746,13.262 19.503,11.06L19.205,11.363C21.412,13.529 23,15.952 23.785,18.078C24.177,19.142 24.366,20.122 24.337,20.954C24.308,21.785 24.063,22.455 23.604,22.923L23.907,23.221ZM16.917,23.551C18.263,23.991 19.641,24.273 20.862,24.267C22.08,24.262 23.173,23.969 23.907,23.221L23.604,22.923C22.982,23.556 22.023,23.837 20.86,23.842C19.7,23.848 18.37,23.579 17.049,23.147L16.917,23.551ZM26.325,25.868C25.332,26.86 23.847,27.257 22.071,27.09C20.294,26.923 18.248,26.191 16.177,24.957L15.959,25.322C18.069,26.579 20.175,27.338 22.031,27.513C23.886,27.688 25.514,27.279 26.625,26.168L26.325,25.868ZM15.392,24.311C15.392,24.721 15.601,25.109 15.959,25.322L16.177,24.957C15.953,24.823 15.816,24.578 15.816,24.311H15.392ZM6.626,14.087C6.942,14.087 7.162,13.783 7.079,13.486L6.67,13.6C6.679,13.633 6.653,13.662 6.626,13.662V14.087ZM17.049,23.147C16.257,22.888 15.392,23.453 15.392,24.311H15.816C15.816,23.766 16.377,23.375 16.917,23.551L17.049,23.147ZM6.181,13.762C6.243,13.957 6.424,14.087 6.626,14.087V13.662C6.607,13.662 6.591,13.649 6.586,13.633L6.181,13.762Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="6.676"
android:startY="4.969"
android:endX="28.925"
android:endY="21.066"
android:type="linear">
<item android:offset="0" android:color="#FFF9CC2E"/>
<item android:offset="1" android:color="#00F9CC2E"/>
</gradient>
</aapt:attr>
</path>
</group>
<path
android:pathData="M13.685,19.796C13.669,19.044 14.682,18.789 15.024,19.459L15.581,20.551C15.68,20.745 15.863,20.883 16.077,20.924L17.698,21.238C18.288,21.352 18.477,22.103 18.011,22.482L16.732,23.526C16.563,23.664 16.467,23.872 16.472,24.09L16.497,25.315C16.513,26.067 15.5,26.322 15.158,25.652L14.601,24.561C14.502,24.366 14.319,24.229 14.105,24.187L12.484,23.873C11.894,23.759 11.705,23.009 12.17,22.629L13.45,21.585C13.619,21.447 13.715,21.24 13.71,21.021L13.685,19.796Z"
android:fillColor="#F9FAFA"/>
<path
android:pathData="M12.707,15.909C12.691,15.157 13.704,14.902 14.046,15.572L16.011,19.42C16.11,19.615 16.293,19.752 16.507,19.794L20.417,20.551C21.007,20.665 21.196,21.415 20.731,21.795L17.644,24.313C17.475,24.451 17.379,24.659 17.384,24.877L17.475,29.197C17.491,29.949 16.478,30.204 16.136,29.534L14.171,25.685C14.072,25.491 13.889,25.353 13.675,25.312L9.765,24.555C9.175,24.44 8.986,23.69 9.452,23.31L12.538,20.792C12.707,20.655 12.803,20.447 12.798,20.229L12.707,15.909Z"
android:fillColor="#F9CC2E"
android:fillAlpha="0.54"/>
<path
android:pathData="M12.814,15.907C12.8,15.267 13.661,15.051 13.952,15.62L15.916,19.469C16.03,19.692 16.241,19.85 16.487,19.898L20.397,20.655C20.899,20.752 21.059,21.39 20.663,21.713L17.577,24.23C17.383,24.389 17.272,24.628 17.278,24.879L17.369,29.199C17.382,29.838 16.521,30.055 16.23,29.485L14.266,25.637C14.152,25.413 13.941,25.255 13.695,25.207L9.785,24.45C9.284,24.353 9.123,23.715 9.519,23.392L12.605,20.875C12.799,20.716 12.91,20.477 12.905,20.226L12.814,15.907Z"
android:strokeWidth="0.2125"
android:fillColor="#00000000">
<aapt:attr name="android:strokeColor">
<gradient
android:startX="6.449"
android:startY="14.379"
android:endX="25.116"
android:endY="18.685"
android:type="linear">
<item android:offset="0" android:color="#FFF9CC2E"/>
<item android:offset="1" android:color="#00F9CC2E"/>
</gradient>
</aapt:attr>
</path>
</vector>
Loading