Skip to content
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
7 changes: 0 additions & 7 deletions app/src/main/java/com/into/websoso/data/mapper/UserMapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import com.into.websoso.data.model.UserFeedsEntity.UserFeedEntity
import com.into.websoso.data.model.UserInfoDetailEntity
import com.into.websoso.data.model.UserInfoEntity
import com.into.websoso.data.model.UserNovelStatsEntity
import com.into.websoso.data.model.UserProfileStatusEntity
import com.into.websoso.data.model.UserStorageEntity
import com.into.websoso.data.model.UserStorageEntity.StorageNovelEntity
import com.into.websoso.data.remote.response.BlockedUsersResponseDto
Expand All @@ -26,7 +25,6 @@ import com.into.websoso.data.remote.response.UserFeedsResponseDto.UserFeedRespon
import com.into.websoso.data.remote.response.UserInfoDetailResponseDto
import com.into.websoso.data.remote.response.UserInfoResponseDto
import com.into.websoso.data.remote.response.UserNovelStatsResponseDto
import com.into.websoso.data.remote.response.UserProfileStatusResponseDto
import com.into.websoso.data.remote.response.UserStorageResponseDto
import com.into.websoso.data.remote.response.UserStorageResponseDto.StorageNovelDto
import com.into.websoso.ui.main.myPage.myActivity.model.Genres
Expand Down Expand Up @@ -65,11 +63,6 @@ fun UserNovelStatsResponseDto.toData(): UserNovelStatsEntity =
quitNovelCount = quitNovelCount,
)

fun UserProfileStatusResponseDto.toData(): UserProfileStatusEntity =
Copy link
Member Author

Choose a reason for hiding this comment

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

Boolean 값 하나만 DTO 로 오는데 Entity 까지는 불필요하다고 판단했습니다.
또한, 다른 코드와 얼라인을 맞추기 위해 Entity 삭제와 Mapper 함수 삭제했습니다.

UserProfileStatusEntity(
isProfilePublic = isProfilePublic,
)

fun MyProfileResponseDto.toData(): MyProfileEntity =
MyProfileEntity(
nickname = this.nickname,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import com.into.websoso.data.model.UserFeedsEntity
import com.into.websoso.data.model.UserInfoDetailEntity
import com.into.websoso.data.model.UserInfoEntity
import com.into.websoso.data.model.UserNovelStatsEntity
import com.into.websoso.data.model.UserProfileStatusEntity
import com.into.websoso.data.model.UserStorageEntity
import com.into.websoso.data.remote.api.UserApi
import com.into.websoso.data.remote.request.TermsAgreementRequestDto
Expand Down Expand Up @@ -69,7 +68,7 @@ class UserRepository

suspend fun fetchUserNovelStats(userId: Long): UserNovelStatsEntity = userApi.getUserNovelStats(userId).toData()

suspend fun fetchUserProfileStatus(): UserProfileStatusEntity = userApi.getProfileStatus().toData()
suspend fun fetchUserProfileStatus(): Boolean = userApi.getProfileStatus().isProfilePublic

suspend fun saveUserProfileStatus(isProfilePublic: Boolean) {
userApi.patchProfileStatus(UserProfileStatusRequestDto(isProfilePublic))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,100 +4,58 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import com.into.websoso.R
import com.into.websoso.core.common.ui.base.BaseActivity
import com.into.websoso.core.common.ui.model.ResultFrom.ChangeProfileDisclosure
import com.into.websoso.core.common.util.SingleEventHandler
import com.into.websoso.databinding.ActivityProfileDisclosureBinding
import com.into.websoso.ui.setting.SettingActivity
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class ProfileDisclosureActivity :
BaseActivity<ActivityProfileDisclosureBinding>(R.layout.activity_profile_disclosure) {
class ProfileDisclosureActivity : BaseActivity<ActivityProfileDisclosureBinding>(R.layout.activity_profile_disclosure) {
private val profileDisclosureViewModel: ProfileDisclosureViewModel by viewModels()
private val singleEventHandler: SingleEventHandler by lazy { SingleEventHandler.from() }

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

bindViewModel()
onBackButtonClick()
onProfileDisclosureButtonClick()
onCompleteButtonClick()
setupObserver()
}

private fun bindViewModel() {
binding.profileDisclosureViewModel = profileDisclosureViewModel
binding.lifecycleOwner = this
binding.onToggleClick = ::updateProfileDisclosureStatus
}

private fun onBackButtonClick() {
binding.ivProfileDisclosureBackButton.setOnClickListener {
finish()
}
}

private fun onProfileDisclosureButtonClick() {
binding.clProfileDisclosureButton.setOnClickListener {
profileDisclosureViewModel.updateProfileStatus()
}
}

private fun onCompleteButtonClick() {
binding.tvProfileDisclosureCompleteButton.setOnClickListener {
profileDisclosureViewModel.saveProfileDisclosureStatus()
}
}

private fun setupObserver() {
profileDisclosureViewModel.uiState.observe(this) { uiState ->
when {
uiState.loading -> {
binding.wllProfileDisclosure.setWebsosoLoadingVisibility(true)
binding.wllProfileDisclosure.setErrorLayoutVisibility(false)
}

uiState.error -> {
binding.wllProfileDisclosure.setWebsosoLoadingVisibility(false)
binding.wllProfileDisclosure.setErrorLayoutVisibility(true)
}

else -> {
binding.wllProfileDisclosure.setWebsosoLoadingVisibility(false)
binding.wllProfileDisclosure.setErrorLayoutVisibility(false)
}
}
}

profileDisclosureViewModel.isProfilePublic.observe(this) { isProfilePublic ->
updateProfileDisclosureStatusButton(isProfilePublic)
}

profileDisclosureViewModel.isSaveStatusComplete.observe(this) { isSaveStatus ->
if (isSaveStatus) {
if (profileDisclosureViewModel.isChangedStatus.value == true) {
val intent = SettingActivity.getIntent(
this,
profileDisclosureViewModel.isProfilePublic.value ?: true,
profileDisclosureViewModel.isProfilePrivate.value?.not() ?: true,
)
setResult(ChangeProfileDisclosure.RESULT_OK, intent)
finish()
}
finish()
}
}

private fun updateProfileDisclosureStatusButton(isProfilePublic: Boolean) {
val buttonImage = when (isProfilePublic) {
true -> R.drawable.img_account_info_check_unselected
false -> R.drawable.img_account_info_check_selected
private fun updateProfileDisclosureStatus() {
val newCheckedState: Boolean = !binding.scProfileDisclosureToggle.isChecked
binding.scProfileDisclosureToggle.isChecked = newCheckedState

singleEventHandler.debounce(coroutineScope = lifecycleScope) {
profileDisclosureViewModel.updateProfileStatus(newCheckedState)
}
binding.ivProfileDisclosureStatusButton.setImageResource(buttonImage)
}

companion object {
const val IS_PROFILE_PUBLIC = "isProfilePublic"

fun getIntent(context: Context): Intent {
return Intent(context, ProfileDisclosureActivity::class.java)
}
fun getIntent(context: Context): Intent = Intent(context, ProfileDisclosureActivity::class.java)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,86 +5,46 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.into.websoso.data.repository.UserRepository
import com.into.websoso.ui.profileDisclosure.model.ProfileDisclosureUiState
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class ProfileDisclosureViewModel @Inject constructor(
private val userRepository: UserRepository,
) : ViewModel() {
private val _uiState: MutableLiveData<ProfileDisclosureUiState> =
MutableLiveData(ProfileDisclosureUiState())
val uiState: LiveData<ProfileDisclosureUiState> get() = _uiState
class ProfileDisclosureViewModel
@Inject
constructor(
private val userRepository: UserRepository,
) : ViewModel() {
private var isInitializeOfProfilePrivate: Boolean = false

private val _isProfilePublic: MutableLiveData<Boolean> = MutableLiveData()
val isProfilePublic: LiveData<Boolean> get() = _isProfilePublic
private var _isChangedStatus: MutableLiveData<Boolean> = MutableLiveData(false)
val isChangedStatus: LiveData<Boolean> get() = _isChangedStatus

private val _isCompleteButtonEnabled: MutableLiveData<Boolean> = MutableLiveData(false)
val isCompleteButtonEnabled: LiveData<Boolean> get() = _isCompleteButtonEnabled
val isProfilePrivate: MutableLiveData<Boolean> = MutableLiveData()

private var isInitializeOfProfilePublic: Boolean = false

private val _isSaveStatusComplete: MutableLiveData<Boolean> = MutableLiveData(false)
val isSaveStatusComplete: LiveData<Boolean> get() = _isSaveStatusComplete

init {
updateProfileDisclosureStatus()
}

private fun updateProfileDisclosureStatus() {
viewModelScope.launch {
runCatching {
userRepository.fetchUserProfileStatus()
}.onSuccess { userProfileStatusEntity ->
_uiState.value = uiState.value?.copy(
loading = false,
)
_isProfilePublic.value = userProfileStatusEntity.isProfilePublic
isInitializeOfProfilePublic = userProfileStatusEntity.isProfilePublic
updateIsCompleteButtonEnabled()
}.onFailure {
_uiState.value = uiState.value?.copy(
loading = false,
error = true,
)
}
init {
updateInitialProfileStatus()
}
}

private fun updateIsCompleteButtonEnabled() {
when (isInitializeOfProfilePublic == isProfilePublic.value) {
true -> _isCompleteButtonEnabled.value = false
false -> _isCompleteButtonEnabled.value = true
private fun updateInitialProfileStatus() {
viewModelScope.launch {
runCatching {
userRepository.fetchUserProfileStatus()
}.onSuccess { isPublic ->
isProfilePrivate.value = !isPublic
isInitializeOfProfilePrivate = !isPublic
}
}
}
}

fun updateProfileStatus() {
_isProfilePublic.value = _isProfilePublic.value?.not()
updateIsCompleteButtonEnabled()
}

fun saveProfileDisclosureStatus() {
_uiState.value = uiState.value?.copy(
loading = true,
)
viewModelScope.launch {
runCatching {
val isProfilePublicValue =
isProfilePublic.value ?: isInitializeOfProfilePublic.not()
userRepository.saveUserProfileStatus(isProfilePublicValue)
}.onSuccess {
_uiState.value = uiState.value?.copy(
loading = false,
)
_isSaveStatusComplete.value = true
}.onFailure {
_uiState.value = uiState.value?.copy(
loading = false,
error = true,
)
fun updateProfileStatus(isPrivate: Boolean) {
viewModelScope.launch {
runCatching {
userRepository.saveUserProfileStatus(isPrivate.not())
}.onSuccess {
_isChangedStatus.value = isInitializeOfProfilePrivate == !isPrivate
isProfilePrivate.value = isPrivate
}
}
}
}
}

This file was deleted.

48 changes: 16 additions & 32 deletions app/src/main/res/layout/activity_profile_disclosure.xml
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>

<variable
name="profileDisclosureViewModel"
type="com.into.websoso.ui.profileDisclosure.ProfileDisclosureViewModel" />

<variable
name="onToggleClick"
type="kotlin.jvm.functions.Function0" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
Expand Down Expand Up @@ -40,24 +43,11 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/tv_profile_disclosure_complete_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:enabled="@{profileDisclosureViewModel.isCompleteButtonEnabled}"
android:padding="10dp"
android:text="@string/profile_disclosure_complete"
android:textAppearance="@style/title2"
android:textColor="@color/bg_profile_disclosure_text_selector"
app:layout_constraintBottom_toBottomOf="@id/tv_profile_disclosure_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_profile_disclosure_title" />

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_profile_disclosure_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:onClick="@{() -> onToggleClick.invoke()}"
android:paddingHorizontal="20dp"
android:paddingVertical="10dp"
app:layout_constraintEnd_toEndOf="parent"
Expand All @@ -67,32 +57,26 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingVertical="10dp"
android:text="@string/profile_disclosure_private"
android:textAppearance="@style/body1"
android:textColor="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<ImageView
android:id="@+id/iv_profile_disclosure_status_button"
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/sc_profile_disclosure_toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:src="@drawable/img_account_info_check_unselected"
android:layout_height="0dp"
android:background="@null"
android:checked="@{profileDisclosureViewModel.isProfilePrivate}"
android:clickable="false"
android:thumb="@drawable/bg_notification_setting_toggle_thumb"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintTop_toTopOf="parent"
app:track="@drawable/bg_notification_setting_toggle" />
Copy link
Member

Choose a reason for hiding this comment

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

a: 제가 해당 속성을 처음봐서 그런데 어떤 속성인가요??

Copy link
Member Author

Choose a reason for hiding this comment

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

토글 버튼의 트랙(배경 이미지 ?)를 설정하는 친구입니다
스크린샷 2025-04-20 오전 2 34 59
이 이미지에서 동그란 흰색은 thumb / 회색 배경의 타원은 track

Copy link
Member

Choose a reason for hiding this comment

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

오오 아직도 모르는게 많은 xml의 세계...

</androidx.constraintlayout.widget.ConstraintLayout>

<com.into.websoso.core.common.ui.custom.WebsosoLoadingLayout
android:id="@+id/wll_profile_disclosure"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
1 change: 0 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,6 @@

<!-- 프로필 공개여부 뷰 -->
<string name="profile_disclosure_title">프로필 공개 설정</string>
<string name="profile_disclosure_complete">완료</string>
<string name="profile_disclosure_private">비공개</string>
<string name="profile_disclosure_public">전체 공개</string>
<string name="profile_disclosure_message">프로필이 %s로 전환되었어요</string>
Expand Down