Skip to content

Commit

Permalink
Merge pull request #363 from team-yello/feat/#350-profile-quit-reason
Browse files Browse the repository at this point in the history
[FEAT/#350] Profile / 탈퇴 사유 뷰 구현
  • Loading branch information
minju1459 authored Feb 2, 2024
2 parents e12f838 + 76fca66 commit 34f8fee
Show file tree
Hide file tree
Showing 53 changed files with 553 additions and 85 deletions.
5 changes: 5 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@
android:exported="false"
android:screenOrientation="portrait" />

<activity
android:name=".presentation.main.profile.manage.ProfileQuitReasonActivity"
android:exported="false"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="portrait" />
<activity
android:name=".presentation.main.myyello.read.MyYelloReadActivity"
android:exported="false"
Expand Down
28 changes: 21 additions & 7 deletions app/src/main/java/com/el/yello/presentation/main/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import com.el.yello.presentation.util.dp
import com.el.yello.util.amplitude.AmplitudeUtils
import com.el.yello.util.context.yelloSnackbar
import com.example.domain.enum.SubscribeType.CANCELED
import com.example.domain.enum.SubscribeType.NORMAL
import com.example.ui.base.BindingActivity
import com.example.ui.context.toast
import com.example.ui.intent.stringExtra
Expand Down Expand Up @@ -82,12 +83,15 @@ class MainActivity : BindingActivity<ActivityMainBinding>(R.layout.activity_main
}

private fun initBnvItemSelectedListener() {
supportFragmentManager.findFragmentById(R.id.fcv_main) ?: navigateTo<YelloFragment>()
supportFragmentManager.findFragmentById(R.id.fcv_main)
?: navigateTo<YelloFragment>()

binding.bnvMain.setOnItemSelectedListener { menu ->
when (menu.itemId) {
R.id.menu_recommend -> {
AmplitudeUtils.trackEventWithProperties(EVENT_CLICK_RECOMMEND_NAVIGATION)
AmplitudeUtils.trackEventWithProperties(
EVENT_CLICK_RECOMMEND_NAVIGATION,
)
navigateTo<RecommendFragment>()
}

Expand Down Expand Up @@ -195,20 +199,25 @@ class MainActivity : BindingActivity<ActivityMainBinding>(R.layout.activity_main
// TODO : 도메인 모델에 변환된 날짜로 파싱되도록 보완
val expiredDateString = state.data?.expiredDate.toString()
val expiredDate =
SimpleDateFormat(EXPIRED_DATE_FORMAT).parse(expiredDateString)
SimpleDateFormat(EXPIRED_DATE_FORMAT).parse(
expiredDateString,
)
?: return@onEach
val currentDate = Calendar.getInstance().time
val daysDifference = TimeUnit.DAYS.convert(
expiredDate.time - currentDate.time,
TimeUnit.MILLISECONDS,
)
if (daysDifference >= 1) {
if (daysDifference <= 1) {
PayReSubsNoticeDialog.newInstance(expiredDateString)
.show(supportFragmentManager, PAY_RESUBS_DIALOG)
}
}

is Failure -> yelloSnackbar(binding.root, getString(R.string.msg_error))
is Failure -> yelloSnackbar(
binding.root,
getString(R.string.msg_error),
)
}
}.launchIn(lifecycleScope)
}
Expand All @@ -217,7 +226,11 @@ class MainActivity : BindingActivity<ActivityMainBinding>(R.layout.activity_main
viewModel.getNoticeState.flowWithLifecycle(lifecycle)
.onEach { state ->
when (state) {
is Empty -> yelloSnackbar(binding.root, getString(R.string.msg_error))
is Empty -> yelloSnackbar(
binding.root,
getString(R.string.msg_error),
)

is Loading -> return@onEach
is Success -> {
if (!state.data.isAvailable) return@onEach
Expand Down Expand Up @@ -274,7 +287,8 @@ class MainActivity : BindingActivity<ActivityMainBinding>(R.layout.activity_main
const val BACK_PRESSED_INTERVAL = 2000
const val EXPIRED_DATE_FORMAT = "yyyy-MM-dd"
const val PAY_RESUBS_DIALOG = "PayResubsNoticeDialog"
private const val EVENT_CLICK_RECOMMEND_NAVIGATION = "click_recommend_navigation"
private const val EVENT_CLICK_RECOMMEND_NAVIGATION =
"click_recommend_navigation"

private const val TAG_NOTICE_DIALOG = "NOTICE_DIALOG"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package com.el.yello.presentation.main.profile

import android.content.Context
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.el.yello.R
import com.el.yello.util.amplitude.AmplitudeUtils
import com.example.domain.entity.PayInfoModel
import com.example.domain.entity.ProfileFriendsListModel
import com.example.domain.entity.ProfileQuitReasonModel
import com.example.domain.entity.ProfileUserModel
import com.example.domain.repository.AuthRepository
import com.example.domain.repository.PayRepository
Expand Down Expand Up @@ -69,6 +75,21 @@ class ProfileViewModel @Inject constructor(
var clickedUserData = ProfileUserModel()
var clickedItemPosition: Int? = null

private val quitReasonText = MutableLiveData<String>()
val etcText = MutableLiveData("")
private val _quitReasonData: MutableLiveData<List<String>> = MutableLiveData()
val quitReasonData: LiveData<List<String>> = _quitReasonData
fun setEtcText(etc: String) {
etcText.value = etc
}
fun setQuitReason(reason: String) {
quitReasonText.value = reason
}
fun addQuitReasonList(context: Context) {
val quitReasonArray = context.resources.getStringArray(R.array.quit_reasons)
_quitReasonData.value = quitReasonArray.toList()
}

fun setItemPosition(position: Int) {
clickedItemPosition = position
}
Expand Down Expand Up @@ -135,7 +156,16 @@ class ProfileViewModel @Inject constructor(
fun deleteUserDataToServer() {
viewModelScope.launch {
_deleteUserState.value = UiState.Loading
profileRepository.deleteUserData()
val quitReason = if (quitReasonText.value.toString().equals("기타")) {
etcText.value.toString()
} else {
quitReasonText.value.toString()
}
profileRepository.deleteUserData(
ProfileQuitReasonModel(
quitReason,
),
)
.onSuccess {
clearLocalInfo()
delay(300)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ class ProfileQuitDialog :
viewModel.deleteUserDataToServer()
}
}

// 유저 탈퇴 서버 통신 성공 시 카카오 연결 해제 진행
private fun observeUserDeleteState() {
viewModel.deleteUserState.flowWithLifecycle(lifecycle).onEach { state ->
when (state) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.el.yello.presentation.main.profile.manage

import android.os.Bundle
import androidx.activity.viewModels
import androidx.recyclerview.widget.RecyclerView
import com.el.yello.R
import com.el.yello.databinding.ActivityProfileQuitReasonBinding
import com.el.yello.presentation.main.profile.ProfileViewModel
import com.example.ui.base.BindingActivity
import com.example.ui.context.colorOf
import com.example.ui.view.setOnSingleClickListener
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class ProfileQuitReasonActivity :
BindingActivity<ActivityProfileQuitReasonBinding>(R.layout.activity_profile_quit_reason) {
private lateinit var quitReasonList: List<String>
private val viewModel by viewModels<ProfileViewModel>()
private var clickedItemPosition: Int = RecyclerView.NO_POSITION
private var isItemClicked: Boolean = false
private var profileQuitDialog: ProfileQuitDialog? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding.vm = viewModel
initQuitReasonAdapter()
initBackBtnListener()
initInviteDialogBtnListener()
}

private fun initQuitReasonAdapter() {
viewModel.addQuitReasonList(this)
quitReasonList = viewModel.quitReasonData.value ?: emptyList()
val adapter = ProfileQuitReasonAdapter(
storeQuitReason = ::storeQuitReason,
setEtcText = ::setEtcText,
) { position, clicked ->
clickedItemPosition = position
isItemClicked = clicked
if (isItemClicked) {
if (clickedItemPosition == 7) {
nonClickedButtonUI()
} else {
clickedButtonUI()
}
}
}
binding.rvQuitReason.adapter = adapter
adapter.submitList(ArrayList(quitReasonList))
}

private fun initInviteDialogBtnListener() {
binding.btnProfileQuitReasonDone.setOnSingleClickListener {
profileQuitDialog = ProfileQuitDialog()
profileQuitDialog?.show(supportFragmentManager, QUIT_DIALOG)
}
}

private fun initBackBtnListener() {
binding.btnProfileQuitReasonBack.setOnSingleClickListener { finish() }
}

private fun clickedButtonUI() {
with(binding.btnProfileQuitReasonDone) {
setBackgroundResource(R.drawable.shape_black_fill_grayscales700_line_100_rect)
setTextColor(colorOf(R.color.semantic_red_500))
isEnabled = true
}
}

private fun nonClickedButtonUI() {
with(binding.btnProfileQuitReasonDone) {
setBackgroundResource(R.drawable.shape_black_fill_grayscales600_line_100_rect)
setTextColor(colorOf(R.color.grayscales_600))
isEnabled = false
}
}

private fun storeQuitReason(reason: String) {
viewModel.setQuitReason(reason)
}

private fun setEtcText(etc: String) {
viewModel.setEtcText(etc)
}

override fun onDestroy() {
super.onDestroy()
profileQuitDialog?.dismiss()
}

private companion object {
const val QUIT_DIALOG = "quitDialog"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.el.yello.presentation.main.profile.manage

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.widget.addTextChangedListener
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.el.yello.R
import com.el.yello.databinding.ItemProfileQuitReasonBinding
import com.example.ui.view.ItemDiffCallback
import com.example.ui.view.setOnSingleClickListener

class ProfileQuitReasonAdapter(
private val storeQuitReason: (String) -> Unit,
private val setEtcText: (String) -> Unit,
private val onItemClickListener: (Int, Boolean) -> Unit,
) : ListAdapter<String, ProfileQuitReasonAdapter.QuitReasonViewHolder>(diffUtil) {
private var selectedItemPosition: Int = RecyclerView.NO_POSITION
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QuitReasonViewHolder {
return QuitReasonViewHolder(
ItemProfileQuitReasonBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false,
),
storeQuitReason,
setEtcText,
this::onItemClicked,
)
}

override fun onBindViewHolder(holder: QuitReasonViewHolder, position: Int) {
holder.bind(getItem(position), position == selectedItemPosition)
}

private fun onItemClicked(position: Int) {
if (selectedItemPosition != RecyclerView.NO_POSITION) {
notifyItemChanged(selectedItemPosition)
}
selectedItemPosition = position
notifyItemChanged(position)
storeQuitReason(getItem(position))
onItemClickListener(position, true)
}

class QuitReasonViewHolder(
private val binding: ItemProfileQuitReasonBinding,
private val storeQuitReason: (String) -> Unit,
private val setEtcText: (String) -> Unit,
private val onItemClicked: (Int) -> Unit,
) : RecyclerView.ViewHolder(binding.root) {

fun bind(reason: String, isItemSelected: Boolean) {
binding.reason = reason
binding.root.setOnSingleClickListener {
onItemClicked(absoluteAdapterPosition)
}
binding.etQuitEtc.addTextChangedListener {
setEtcText(binding.etQuitEtc.text.toString())
}
if (isItemSelected) {
with(binding) {
ivQuitReasonCheckpoint.setBackgroundResource(R.drawable.ic_profile_quit_reason_check)
cvQuitReasonList.setBackgroundResource(R.drawable.shape_black_fill_white_line_8_rect)
etQuitEtc.visibility = if (absoluteAdapterPosition == 7) View.VISIBLE else View.GONE
}
storeQuitReason(reason)
} else {
with(binding) {
ivQuitReasonCheckpoint.setBackgroundResource(R.drawable.ic_profile_quit_reason_uncheck)
cvQuitReasonList.setBackgroundResource(R.drawable.shape_grayscales900_fill_8_rect)
etQuitEtc.visibility = View.GONE
}
}
}
}

companion object {
private val diffUtil = ItemDiffCallback<String>(
onItemsTheSame = { old, new -> old == new },
onContentsTheSame = { old, new -> old == new },
)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.el.yello.presentation.main.profile.manage

import android.content.Intent
import android.os.Bundle
import com.el.yello.R
import com.el.yello.databinding.ActivityProfileQuitTwoBinding
Expand All @@ -12,37 +13,27 @@ import org.json.JSONObject
@AndroidEntryPoint
class ProfileQuitTwoActivity :
BindingActivity<ActivityProfileQuitTwoBinding>(R.layout.activity_profile_quit_two) {

private var profileQuitDialog: ProfileQuitDialog? = null

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

initBackBtnListener()
initInviteDialogBtnListener()
initQuitBtnListener()
}

private fun initBackBtnListener() {
binding.btnProfileQuitBack.setOnSingleClickListener { finish() }
}

private fun initInviteDialogBtnListener() {
private fun initQuitBtnListener() {
binding.btnProfileQuitForSure.setOnSingleClickListener {
AmplitudeUtils.trackEventWithProperties(
"click_profile_withdrawal",
JSONObject().put("withdrawal_button", "withdrawal3"),
)
profileQuitDialog = ProfileQuitDialog()
profileQuitDialog?.show(supportFragmentManager, QUIT_DIALOG)
Intent(this, ProfileQuitReasonActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(this)
}
}
}

override fun onDestroy() {
super.onDestroy()
profileQuitDialog?.dismiss()
}

private companion object {
const val QUIT_DIALOG = "quitDialog"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.el.yello.presentation.onboarding.activity
package com.el.yello.presentation.onboarding

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
Expand Down
Loading

0 comments on commit 34f8fee

Please sign in to comment.