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
2 changes: 1 addition & 1 deletion CatchMate/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ android {
defaultConfig {
applicationId = "com.catchmate.android"
versionCode = 1
versionName = "1.0"
versionName = "1.0.0"

buildConfigField("String", "KAKAO_NATIVE_APP_KEY", kakaoNativeAppKey)
buildConfigField("String", "NAVER_CLIENT_ID", naverClientId)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.catchmate.data.datasource.remote

import com.catchmate.data.dto.user.DeleteBlockedUserResponseDTO
import com.catchmate.data.dto.user.DeleteUserAccountResponseDTO
import com.catchmate.data.dto.user.GetBlockedUserListResponseDTO
import com.catchmate.data.dto.user.GetUnreadInfoResponseDTO
import com.catchmate.data.dto.user.GetUserProfileByIdResponseDTO
Expand Down Expand Up @@ -68,4 +69,7 @@ interface UserService {
suspend fun deleteBlockedUser(
@Path("blockedUserId") blockedUserId: Long,
): Response<DeleteBlockedUserResponseDTO?>

@DELETE("users/withdraw")
suspend fun deleteUserAccount(): Response<DeleteUserAccountResponseDTO?>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.catchmate.data.dto.user

data class DeleteUserAccountResponseDTO(
val state: Boolean,
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.catchmate.data.mapper

import com.catchmate.data.dto.user.DeleteBlockedUserResponseDTO
import com.catchmate.data.dto.user.DeleteUserAccountResponseDTO
import com.catchmate.data.dto.user.GetBlockedUserListResponseDTO
import com.catchmate.data.dto.user.GetUnreadInfoResponseDTO
import com.catchmate.data.dto.user.GetUserProfileByIdResponseDTO
Expand All @@ -12,6 +13,7 @@ import com.catchmate.data.dto.user.PostUserAdditionalInfoResponseDTO
import com.catchmate.data.dto.user.PostUserBlockResponseDTO
import com.catchmate.data.mapper.BoardMapper.toFavoriteClub
import com.catchmate.domain.model.user.DeleteBlockedUserResponse
import com.catchmate.domain.model.user.DeleteUserAccountResponse
import com.catchmate.domain.model.user.GetBlockedUserListResponse
import com.catchmate.domain.model.user.GetUnreadInfoResponse
import com.catchmate.domain.model.user.GetUserProfileByIdResponse
Expand Down Expand Up @@ -114,4 +116,9 @@ object UserMapper {
hasUnreadChat = dto.hasUnreadChat,
hasUnreadNotification = dto.hasUnreadNotification,
)

fun toDeleteUserAccountResponse(dto: DeleteUserAccountResponseDTO): DeleteUserAccountResponse =
DeleteUserAccountResponse(
state = dto.state,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import com.catchmate.data.datasource.remote.RetrofitClient
import com.catchmate.data.datasource.remote.UserService
import com.catchmate.data.mapper.UserMapper
import com.catchmate.data.mapper.UserMapper.toDeleteBlockedUserResponse
import com.catchmate.data.mapper.UserMapper.toDeleteUserAccountResponse
import com.catchmate.data.mapper.UserMapper.toGetBlockedUserListResponse
import com.catchmate.data.mapper.UserMapper.toGetUnreadInfoResponse
import com.catchmate.data.mapper.UserMapper.toPostUserBlockResponse
import com.catchmate.domain.exception.ReissueFailureException
import com.catchmate.domain.exception.UserBlockFailureException
import com.catchmate.domain.model.user.DeleteBlockedUserResponse
import com.catchmate.domain.model.user.DeleteUserAccountResponse
import com.catchmate.domain.model.user.GetBlockedUserListResponse
import com.catchmate.domain.model.user.GetUnreadInfoResponse
import com.catchmate.domain.model.user.GetUserProfileByIdResponse
Expand Down Expand Up @@ -228,4 +230,21 @@ class UserRepositoryImpl
} catch (e: Exception) {
Result.failure(e)
}

override suspend fun deleteUserAccount(): Result<DeleteUserAccountResponse> =
try {
val response = userApi.deleteUserAccount()
if (response.isSuccessful) {
Log.d("UserRepo", "통신 성공 : ${response.code()}")
val body = response.body()?.let { toDeleteUserAccountResponse(it) } ?: throw NullPointerException("Null Response")
Result.success(body)
} else {
val stringToJson = JSONObject(response.errorBody()?.string()!!)
Result.failure(Exception("UserRepo 통신 실패 : ${response.code()} - $stringToJson"))
}
} catch (e: ReissueFailureException) {
Result.failure(e)
} catch (e: Exception) {
Result.failure(e)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.catchmate.domain.model.user

data class DeleteUserAccountResponse(
val state: Boolean,
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.catchmate.domain.repository

import com.catchmate.domain.model.user.DeleteBlockedUserResponse
import com.catchmate.domain.model.user.DeleteUserAccountResponse
import com.catchmate.domain.model.user.GetBlockedUserListResponse
import com.catchmate.domain.model.user.GetUnreadInfoResponse
import com.catchmate.domain.model.user.GetUserProfileByIdResponse
Expand Down Expand Up @@ -37,4 +38,6 @@ interface UserRepository {
): Result<PatchUserAlarmResponse>

suspend fun deleteBlockedUser(blockedUserId: Long): Result<DeleteBlockedUserResponse>

suspend fun deleteUserAccount(): Result<DeleteUserAccountResponse>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.catchmate.domain.usecase.user

import com.catchmate.domain.model.user.DeleteUserAccountResponse
import com.catchmate.domain.repository.UserRepository
import javax.inject.Inject

class DeleteUserAccountUseCase
@Inject
constructor(
private val userRepository: UserRepository,
) {
suspend operator fun invoke(): Result<DeleteUserAccountResponse> = userRepository.deleteUserAccount()
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ class LoginFragment : BaseFragment<FragmentLoginBinding>(FragmentLoginBinding::i
val bundle = Bundle()
bundle.putSerializable("userInfo", userInfo)
findNavController().navigate(R.id.action_loginFragment_to_termsAndConditionFragment, bundle)
loginViewModel.initPostLoginRequest()
loginViewModel.initPostLoginResponse()
}
false -> {
localDataViewModel.saveAccessToken(loginResponse.accessToken!!)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,13 @@ class AccountInfoFragment : BaseFragment<FragmentAccountInfoBinding>(FragmentAcc
localDataViewModel.refreshToken.observe(viewLifecycleOwner) { token ->
if (token != null) {
initLogoutBtn()
initWithdrawBtn()
}
}
accountInfoViewModel.logoutResponse.observe(viewLifecycleOwner) { response ->
Log.e("LOGOUT", response.state.toString())
// 로그아웃 시 로컬 데이터 삭제 및 화면 이동
localDataViewModel.logout()
localDataViewModel.logoutAndWithdraw()
val navOptions =
NavOptions
.Builder()
Expand All @@ -99,6 +100,17 @@ class AccountInfoFragment : BaseFragment<FragmentAccountInfoBinding>(FragmentAcc
Log.e("Reissue Error", it)
}
}
accountInfoViewModel.withdrawResponse.observe(viewLifecycleOwner) { response ->
if (response.state) {
localDataViewModel.logoutAndWithdraw()
val navOptions =
NavOptions
.Builder()
.setPopUpTo(R.id.accountInfoFragment, true)
.build()
findNavController().navigate(R.id.action_accountInfoFragment_to_loginFragment, null, navOptions)
}
}
}

private fun initLogoutBtn() {
Expand All @@ -110,4 +122,10 @@ class AccountInfoFragment : BaseFragment<FragmentAccountInfoBinding>(FragmentAcc
}
}
}

private fun initWithdrawBtn() {
binding.tvAccountInfoDeleteAccount.setOnClickListener {
accountInfoViewModel.withdraw()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.navigation.NavOptions
import androidx.navigation.fragment.findNavController
import com.catchmate.domain.model.enumclass.AlarmType
import com.catchmate.domain.model.user.PostUserAdditionalInfoRequest
import com.catchmate.presentation.R
import com.catchmate.presentation.databinding.FragmentCheerStyleOnboardingBinding
Expand All @@ -25,6 +26,7 @@ class CheerStyleOnboardingFragment : BaseFragment<FragmentCheerStyleOnboardingBi
private val mainViewModel: MainViewModel by activityViewModels()

private lateinit var userInfo: PostUserAdditionalInfoRequest
private val pushNotificationAgree by lazy { arguments?.getBoolean("PushNotificationAgree") ?: false }

private var selectedButton: CheerStyleButtonView? = null

Expand Down Expand Up @@ -136,6 +138,8 @@ class CheerStyleOnboardingFragment : BaseFragment<FragmentCheerStyleOnboardingBi
localDataViewModel.saveUserId(response.userId)
localDataViewModel.saveProvider(userInfo.provider)
mainViewModel.setGuestLogin(false)
val isEnabled = if (pushNotificationAgree) "Y" else "N"
signUpViewModel.patchUserAlarm(AlarmType.ALL.name, isEnabled)
findNavController().navigate(R.id.action_cheerStyleOnboardingFragment_to_signupCompleteFragment)
}
}
Expand All @@ -156,5 +160,8 @@ class CheerStyleOnboardingFragment : BaseFragment<FragmentCheerStyleOnboardingBi
signUpViewModel.errorMessage.observe(viewLifecycleOwner) { message ->
Log.e("SIGN UP ERR", message.toString())
}
signUpViewModel.patchUserAlarmResponse.observe(viewLifecycleOwner) { response ->
Log.d("알림 설정 완료", "${response.alarmType} - ${response.isEnabled}")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import dagger.hilt.android.AndroidEntryPoint
class SignupFragment : BaseFragment<FragmentSignupBinding>(FragmentSignupBinding::inflate) {
private val signUpViewModel: SignUpViewModel by viewModels()
private lateinit var userInfo: PostUserAdditionalInfoRequest
private val pushNotificationAgree by lazy { arguments?.getBoolean("PushNotificationAgree") ?: false }

private val handler = Handler(Looper.getMainLooper())
private var runnable: Runnable? = null
Expand Down Expand Up @@ -86,6 +87,7 @@ class SignupFragment : BaseFragment<FragmentSignupBinding>(FragmentSignupBinding
)
val bundle = Bundle()
bundle.putSerializable("userInfo", newUserInfo)
bundle.putBoolean("PushNotificationAgree", pushNotificationAgree)

findNavController().navigate(R.id.action_signupFragment_to_teamOnboardingFragment, bundle)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.catchmate.presentation.view.base.BaseFragment

class TeamOnboardingFragment : BaseFragment<FragmentTeamOnboardingBinding>(FragmentTeamOnboardingBinding::inflate) {
private lateinit var userInfo: PostUserAdditionalInfoRequest
private val pushNotificationAgree by lazy { arguments?.getBoolean("PushNotificationAgree") ?: false }

private var selectedButton: TeamButtonView? = null

Expand Down Expand Up @@ -104,6 +105,7 @@ class TeamOnboardingFragment : BaseFragment<FragmentTeamOnboardingBinding>(Fragm
)
val bundle = Bundle()
bundle.putSerializable("userInfo", newUserInfo)
bundle.putBoolean("PushNotificationAgree", pushNotificationAgree)
findNavController().navigate(R.id.action_teamOnboardingFragment_to_cheerStyleOnboardingFragment, bundle)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.catchmate.presentation.view.onboarding

import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.navigation.fragment.findNavController
import com.catchmate.domain.model.user.PostUserAdditionalInfoRequest
import com.catchmate.presentation.R
import com.catchmate.presentation.databinding.FragmentTermsAndConditionBinding
import com.catchmate.presentation.view.base.BaseFragment
Expand All @@ -12,15 +14,24 @@ class TermsAndConditionFragment : BaseFragment<FragmentTermsAndConditionBinding>
private var isFirstChecked = false
private var isSecondChecked = false
private var isThirdChecked = false
private lateinit var userInfo: PostUserAdditionalInfoRequest

override fun onViewCreated(
view: View,
savedInstanceState: Bundle?,
) {
super.onViewCreated(view, savedInstanceState)
userInfo = getUserInfo()
initView()
}

private fun getUserInfo(): PostUserAdditionalInfoRequest =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
arguments?.getSerializable("userInfo", PostUserAdditionalInfoRequest::class.java)!!
} else {
arguments?.getSerializable("userInfo") as PostUserAdditionalInfoRequest
}

private fun initView() {
binding.apply {
layoutHeaderTermsAndCondition.apply {
Expand All @@ -32,7 +43,10 @@ class TermsAndConditionFragment : BaseFragment<FragmentTermsAndConditionBinding>
layoutFooterTermsAndCondition.btnFooterOne.apply {
setText(R.string.next)
setOnClickListener {
findNavController().navigate(R.id.action_termsAndConditionFragment_to_signupFragment)
val bundle = Bundle()
bundle.putSerializable("userInfo", userInfo)
bundle.putBoolean("PushNotificationAgree", isThirdChecked)
findNavController().navigate(R.id.action_termsAndConditionFragment_to_signupFragment, bundle)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.catchmate.domain.exception.ReissueFailureException
import com.catchmate.domain.model.auth.DeleteLogoutResponse
import com.catchmate.domain.model.user.DeleteUserAccountResponse
import com.catchmate.domain.usecase.auth.DeleteAuthLogoutUseCase
import com.catchmate.domain.usecase.user.DeleteUserAccountUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
Expand All @@ -16,11 +18,16 @@ class AccountInfoViewModel
@Inject
constructor(
private val deleteAuthLogoutUseCase: DeleteAuthLogoutUseCase,
private val deleteUserAccountUseCase: DeleteUserAccountUseCase,
) : ViewModel() {
private val _logoutResponse = MutableLiveData<DeleteLogoutResponse>()
val logoutResponse: LiveData<DeleteLogoutResponse>
get() = _logoutResponse

private val _withdrawResponse = MutableLiveData<DeleteUserAccountResponse>()
val withdrawResponse: LiveData<DeleteUserAccountResponse>
get() = _withdrawResponse

private val _errorMessage = MutableLiveData<String?>()
val errorMessage: LiveData<String?>
get() = _errorMessage
Expand All @@ -44,4 +51,20 @@ class AccountInfoViewModel
}
}
}

fun withdraw() {
viewModelScope.launch {
val result = deleteUserAccountUseCase()
result
.onSuccess { response ->
_withdrawResponse.value = response
}.onFailure { exception ->
if (exception is ReissueFailureException) {
_navigateToLogin.value = true
} else {
_errorMessage.value = exception.message
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class LocalDataViewModel
_provider.value = localDataUseCase.getProvider()
}

fun logout() {
fun logoutAndWithdraw() {
localDataUseCase.removeTokens()
localDataUseCase.removeProvider()
localDataUseCase.removeUserId()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,22 @@ class LoginViewModel
val postLoginRequest: LiveData<PostLoginRequest?>
get() = _postLoginRequest

private val _postLoginResponse = MutableLiveData<PostLoginResponse>()
val postLoginResponse: LiveData<PostLoginResponse>
private val _postLoginResponse = MutableLiveData<PostLoginResponse?>()
val postLoginResponse: LiveData<PostLoginResponse?>
get() = _postLoginResponse

private val _noCredentialException = MutableLiveData<String>()
val noCredentialException: LiveData<String>
get() = _noCredentialException

fun initPostLoginRequest() {
_postLoginRequest.value = null
}

fun initPostLoginResponse() {
_postLoginResponse.value = null
}

fun kakaoLogin() {
viewModelScope.launch {
_postLoginRequest.value = socialLoginUseCase.loginWithKakao()
Expand Down
Loading