Skip to content

Commit

Permalink
Merge pull request #210 from wespot-bff/feature/flash159483/#208
Browse files Browse the repository at this point in the history
#208: 프로필 수정 바텀시트 보여주기
  • Loading branch information
flash159483 authored Dec 17, 2024
2 parents f8e4e2a + ed5710d commit afe8dda
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.bff.wespot.data.remote.source.user

import com.bff.wespot.data.remote.model.user.request.FeatureNotificationSettingDto
import com.bff.wespot.data.remote.model.user.response.NotificationSettingDto
import com.bff.wespot.data.remote.model.user.request.IntroductionDto
import com.bff.wespot.data.remote.model.user.response.NotificationSettingDto
import com.bff.wespot.data.remote.model.user.response.ProfileCharacterDto
import com.bff.wespot.data.remote.model.user.response.UserListDto
import com.bff.wespot.data.remote.model.user.response.ProfileDto
import com.bff.wespot.data.remote.model.user.response.UserListDto

interface UserDataSource {
suspend fun getUserListByName(name: String, cursorId: Int?): Result<UserListDto>
Expand All @@ -24,5 +24,5 @@ interface UserDataSource {

suspend fun updateCharacter(character: ProfileCharacterDto): Result<Unit>

suspend fun updateProfileImage(url: String): Result<Unit>
suspend fun updateProfileImage(url: String?): Result<Unit>
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class UserDataSourceImpl @Inject constructor(
setBody(character)
}

override suspend fun updateProfileImage(url: String): Result<Unit> =
override suspend fun updateProfileImage(url: String?): Result<Unit> =
httpClient.safeRequest {
url {
method = HttpMethod.Post
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class ProfileRepositoryImpl @Inject constructor(

override suspend fun clearProfile() = profileDataSource.clearProfile()

override suspend fun updateProfileImage(url: String): Boolean {
override suspend fun updateProfileImage(url: String?): Boolean {
val response = userDataSource.updateProfileImage(url)
return response.isSuccess
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ interface ProfileRepository {

suspend fun clearProfile()

suspend fun updateProfileImage(url: String): Boolean
suspend fun updateProfileImage(url: String?): Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ internal fun ImageScreen(

val pickImage =
rememberLauncherForActivityResult(contract = ActivityResultContracts.PickVisualMedia()) {
action(AuthAction.ChangeImage(it.toString()))
it?.let {
action(AuthAction.ChangeImage(it.toString()))
}
}

Scaffold(
Expand Down Expand Up @@ -122,7 +124,12 @@ internal fun ImageScreen(
Text(
text = stringResource(id = com.bff.wespot.ui.R.string.introduction),
style = StaticTypeScale.Default.body4,
modifier = Modifier.padding(top = 22.dp, bottom = 12.dp, start = 10.dp, end = 10.dp),
modifier = Modifier.padding(
top = 22.dp,
bottom = 12.dp,
start = 10.dp,
end = 10.dp,
),
)

WsTextField(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
Expand All @@ -34,11 +36,13 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusState
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import androidx.core.view.ViewCompat
Expand All @@ -63,6 +67,7 @@ import com.bff.wespot.navigation.Navigator
import com.bff.wespot.ui.component.LetterCountIndicator
import com.bff.wespot.ui.component.LoadingAnimation
import com.bff.wespot.ui.component.TopToast
import com.bff.wespot.ui.component.WSBottomSheet
import com.bff.wespot.ui.model.ToastState
import com.bff.wespot.ui.util.clickableSingle
import com.bff.wespot.ui.util.handleSideEffect
Expand Down Expand Up @@ -101,7 +106,9 @@ fun ProfileEditScreen(

val pickImage =
rememberLauncherForActivityResult(contract = ActivityResultContracts.PickVisualMedia()) {
action(EntireEditAction.OnProfileImagePicked(it.toString()))
it?.let {
action(EntireEditAction.OnProfileImagePicked(it.toString()))
}
}

handleSideEffect(viewModel.sideEffect)
Expand All @@ -113,7 +120,15 @@ fun ProfileEditScreen(
focusManager.clearFocus()
}

else -> {}
is EntireEditSideEffect.OpenPicker -> {
pickImage.launch(
PickVisualMediaRequest(
ActivityResultContracts.PickVisualMedia.SingleMimeType(
"image/*",
),
),
)
}
}
}

Expand All @@ -138,13 +153,11 @@ fun ProfileEditScreen(
modifier = Modifier
.padding(top = 16.dp)
.clickableSingle {
pickImage.launch(
PickVisualMediaRequest(
ActivityResultContracts.PickVisualMedia.SingleMimeType(
"image/*",
),
),
)
if (state.profilePath.isNullOrEmpty()) {
action(EntireEditAction.OpenPicker)
} else {
action(EntireEditAction.ChangeBottomSheetState(true))
}
},
) {
AsyncImage(
Expand All @@ -153,6 +166,9 @@ fun ProfileEditScreen(
.clip(CircleShape),
model = ImageRequest.Builder(LocalContext.current)
.data(state.profilePath)
.error(com.bff.wespot.designsystem.R.drawable.default_image)
.fallback(com.bff.wespot.designsystem.R.drawable.default_image)
.placeholder(com.bff.wespot.designsystem.R.drawable.default_image)
.crossfade(true)
.build(),
contentDescription = stringResource(
Expand Down Expand Up @@ -225,7 +241,7 @@ fun ProfileEditScreen(
enabled =
isEdited &&
state.hasProfanity.not() &&
state.introductionInput.length in 1..20,
state.introductionInput.length in 0..20,
text = stringResource(id = R.string.edit_done),
content = { it() },
)
Expand Down Expand Up @@ -285,6 +301,49 @@ fun ProfileEditScreen(
}
}

if (state.changeBottomSheet) {
WSBottomSheet(
closeSheet = {
action(EntireEditAction.ChangeBottomSheetState(false))
},
) {
Column(
modifier = Modifier
.fillMaxWidth(),
) {
Text(
text = stringResource(R.string.change_image),
modifier = Modifier
.clickableSingle {
action(EntireEditAction.OpenPicker)
action(EntireEditAction.ChangeBottomSheetState(false))
}
.fillMaxWidth()
.padding(vertical = 16.dp, horizontal = 28.dp)
.clip(RoundedCornerShape(8.dp)),
textAlign = TextAlign.Center,
style = StaticTypeScale.Default.body3,
)
HorizontalDivider(
color = Color(0xFF4F5157),
)
Text(
text = stringResource(R.string.remove_image),
modifier = Modifier
.clickableSingle {
action(EntireEditAction.OnProfileImagePicked(null))
action(EntireEditAction.ChangeBottomSheetState(false))
}
.fillMaxWidth()
.padding(vertical = 16.dp, horizontal = 28.dp)
.clip(RoundedCornerShape(8.dp)),
textAlign = TextAlign.Center,
style = StaticTypeScale.Default.body3,
)
}
}
}

LaunchedEffect(Unit) {
action(EntireEditAction.OnProfileEditScreenEntered(navArgs.isCompleteProfileEdit))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ sealed class EntireEditAction {
data class OnIntroductionChanged(val introduction: String) : EntireEditAction()
data object OnRequestDialogDismissed : EntireEditAction()
data object OnRequestDialogShown : EntireEditAction()
data class OnProfileImagePicked(val profilePath: String) : EntireEditAction()
data class OnProfileImagePicked(val profilePath: String?) : EntireEditAction()
data class ChangeBottomSheetState(val isBottomSheetOpen: Boolean) : EntireEditAction()
data object OpenPicker : EntireEditAction()
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ package com.bff.wespot.entire.state.edit
import com.bff.wespot.ui.model.ToastState

sealed class EntireEditSideEffect {
data object NavigateToEntire : EntireEditSideEffect()
data class ShowToast(val toastState: ToastState) : EntireEditSideEffect()
data object OpenPicker : EntireEditSideEffect()
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ data class EntireEditUiState(
val requestDialog: Boolean = false,
val profilePath: String? = null,
val loading: Boolean = false,
val changeBottomSheet: Boolean = false,
)
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ class EntireEditViewModel @Inject constructor(
is EntireEditAction.OnProfileImagePicked -> {
reduce { state.copy(profilePath = action.profilePath) }
}

is EntireEditAction.ChangeBottomSheetState -> {
reduce { state.copy(changeBottomSheet = action.isBottomSheetOpen) }
}

is EntireEditAction.OpenPicker -> {
postSideEffect(EntireEditSideEffect.OpenPicker)
}
}
}

Expand Down Expand Up @@ -160,6 +168,7 @@ class EntireEditViewModel @Inject constructor(
}

private fun updateIntroduction() = intent {
if (state.profile.introduction == state.introductionInput) return@intent
reduce { state.copy(isLoading = true) }
viewModelScope.launch {
updateProfileIntroductionUseCase(state.introductionInput)
Expand All @@ -178,6 +187,11 @@ class EntireEditViewModel @Inject constructor(
}

private fun uploadProfileImage() = intent {
if (state.profilePath == null) {
updateProfile(null)
return@intent
}

runCatching {
reduce {
state.copy(
Expand All @@ -191,15 +205,15 @@ class EntireEditViewModel @Inject constructor(
postSideEffect(it.toSideEffect())
}.onSuccess {
if (it != null && it.isSuccess) {
val url = it.getOrNull() ?: return@onSuccess
val url = it.getOrNull()
updateProfile(url)
}
}.onFailure {
Timber.e(it)
}
}

private fun updateProfile(url: String) = intent {
private fun updateProfile(url: String?) = intent {
viewModelScope.launch {
runCatching {
profileRepository.updateProfileImage(url)
Expand Down
2 changes: 2 additions & 0 deletions feature/entire/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,6 @@
<string name="blocked_message_load_error_message">차단된 메세지를 불러오는데 실패했어요.</string>
<string name="introduction_placeholder">(ex. 귀염둥이 엥뿌삐 ENFP)</string>
<string name="request">신청</string>
<string name="change_image">앨범에서 사진 선택</string>
<string name="remove_image">기본 이미지 적용</string>
</resources>

0 comments on commit afe8dda

Please sign in to comment.