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

프로필 사진 required 제거 #39

Merged
merged 7 commits into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from 3 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
Expand Up @@ -35,6 +35,9 @@ import com.keyme.presentation.onboarding.guide.Guide03Screen
import com.keyme.presentation.onboarding.guide.Guide04Screen
import com.keyme.presentation.onboarding.nickname.NicknameScreen
import com.keyme.presentation.onboarding.signin.SignInScreen
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.launch

@Composable
Expand All @@ -57,7 +60,6 @@ fun OnboardingScreen(
) {
val coroutineScope = rememberCoroutineScope()
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.animation_signin_background))
val localOnboardingState by viewModel.userAuthState.collectAsState()

val pagerState = rememberPagerState(initialPage = 0)
val onboardingSteps = listOf(
Expand All @@ -69,15 +71,16 @@ fun OnboardingScreen(
OnboardingStepsEnum.GUIDE_04,
)

LaunchedEffect(localOnboardingState) {
localOnboardingState.let {
when {
it?.accessToken == null -> pagerState.scrollToPage(OnboardingStepsEnum.KAKAO_SIGN_IN.ordinal)
it.nickname == null -> pagerState.scrollToPage(OnboardingStepsEnum.NICKNAME.ordinal)
it.onboardingTestResultId == null -> pagerState.scrollToPage(OnboardingStepsEnum.GUIDE_01.ordinal)
else -> navigateToMyDaily.invoke()
LaunchedEffect(key1 = Unit){
viewModel.userAuthState
.collectLatest {
when {
it?.accessToken == null -> pagerState.scrollToPage(OnboardingStepsEnum.KAKAO_SIGN_IN.ordinal)
it.nickname.isNullOrBlank() -> pagerState.scrollToPage(OnboardingStepsEnum.NICKNAME.ordinal)
it.onboardingTestResultId == null -> pagerState.scrollToPage(OnboardingStepsEnum.GUIDE_01.ordinal)
else -> navigateToMyDaily.invoke()
}
}
}
}

when (pagerState.currentPage) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ class OnboardingViewModel @Inject constructor(
originalUrl: String,
thumbnailUrl: String,
) {
if (uploadProfileImageState.value == null) return
// todo 프로필 사진 선택
// if (uploadProfileImageState.value == null) return
apiCall(apiRequest = {
updateMemberUseCase.invoke(
nickname = nickname,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.keyme.presentation.onboarding.nickname

import android.annotation.SuppressLint
import android.net.Uri
import android.util.Base64
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
Expand All @@ -28,7 +27,6 @@ import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
Expand Down Expand Up @@ -70,6 +68,7 @@ import com.keyme.presentation.designsystem.theme.white_alpha_40
import com.keyme.presentation.onboarding.OnboardingViewModel
import com.keyme.presentation.onboarding.fadingAnimateFloatAsState


@Composable
fun NicknameScreen(
isVisible: Boolean,
Expand All @@ -86,16 +85,6 @@ fun NicknameScreen(
ActivityResultContracts.GetContent(),
) { uri -> uri?.let { selectedImage = uri } }

LaunchedEffect(key1 = uploadProfileImageState) {
uploadProfileImageState?.let {
viewModel.updateMember(
nickname = nickname,
originalUrl = it.originalUrl,
thumbnailUrl = it.thumbnailUrl,
)
}
}

Column(
modifier = Modifier
.fillMaxSize()
Expand Down Expand Up @@ -140,7 +129,13 @@ fun NicknameScreen(
nickname = nickname,
isNicknameValidated = verifyNicknameState?.valid ?: false,
selectedImage = selectedImage,
uploadProfileImage = viewModel::uploadProfileImage,
uploadProfileImage = {
viewModel.updateMember(
nickname = nickname,
originalUrl = "",
thumbnailUrl = "",
)
},
)

Spacer(modifier = Modifier.size(54.dp))
Expand Down Expand Up @@ -374,24 +369,24 @@ fun NextButton(
uploadProfileImage: (String) -> Unit,
) {
val context = LocalContext.current
val contentResolver = context.contentResolver

KeymeTextButton(
text = "다음",
onClick = {
if (nickname.isBlank() || !isNicknameValidated) {
Toast.makeText(context, "닉네임을 확인해주세요", Toast.LENGTH_SHORT).show()
} else if (selectedImage == null) {
Toast.makeText(context, "프로필 사진을 선택해주세요", Toast.LENGTH_SHORT).show()
} else {
run {
val inputStream = contentResolver.openInputStream(selectedImage)
val imageBytes = inputStream?.readBytes()
val imageString = Base64.encodeToString(imageBytes, Base64.DEFAULT)
inputStream?.close()

uploadProfileImage.invoke(imageString)
}
}
// todo 프로필 사진 선택
// else if (selectedImage == null) {
// Toast.makeText(context, "프로필 사진을 선택해주세요", Toast.LENGTH_SHORT).show()
// }
else {
// todo 프로필 사진 선택
// val imageString = ImageUploadUtil.getProfileImageString(context, selectedImage)
// imageString?.let {
// uploadProfileImage.invoke(imageString)
// }
uploadProfileImage("")
}
},
modifier = Modifier
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.keyme.presentation.utils

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.util.Base64
import timber.log.Timber
import java.io.ByteArrayOutputStream

object ImageUploadUtil {

fun getProfileImageString(context: Context, uri: Uri): String? {
val resized = resize(context, uri, 360)
val result = resized?.let {
val compressed = compress(it)
Timber.d("><> compressed: ${compressed.byteCount}")
getStringImage(compressed)
}

return result
}

private fun resize(context: Context, uri: Uri, resizePx: Int): Bitmap? {
val options = BitmapFactory.Options()

BitmapFactory.decodeStream(context.contentResolver.openInputStream(uri), null, options)
var width = options.outWidth
var height = options.outHeight
var samplesize = 1
while (width > resizePx || height > resizePx) {
width /= 2
height /= 2
samplesize *= 2
}
options.inSampleSize = samplesize

val resized = BitmapFactory.decodeStream(
context.contentResolver.openInputStream(uri),
null,
options,
)

return resized?.let {
Bitmap.createScaledBitmap(resized, width, height, true)
}
}

private fun compress(bitmap: Bitmap): Bitmap {
val baos = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos)

return BitmapFactory.decodeByteArray(
baos.toByteArray(),
0,
baos.toByteArray().size,
)
}

private fun getStringImage(bitmap: Bitmap): String {
val baos = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val imageBytes = baos.toByteArray()
return Base64.encodeToString(imageBytes, Base64.DEFAULT)
}
}
Loading