Skip to content

Commit

Permalink
✨ Implement logout and withdraw feature
Browse files Browse the repository at this point in the history
  • Loading branch information
89645321 committed Nov 12, 2023
1 parent 240ffb7 commit 0bafd4c
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.example.speechbuddy.compose.utils.AlertDialogUi
import com.example.speechbuddy.compose.utils.ButtonLevel
import com.example.speechbuddy.compose.utils.ButtonUi
import com.example.speechbuddy.compose.utils.HomeTopAppBarUi
import com.example.speechbuddy.compose.utils.ProgressIndicatorUi
import com.example.speechbuddy.compose.utils.TitleUi
import com.example.speechbuddy.ui.models.AccountSettingsAlert
import com.example.speechbuddy.viewmodel.AccountSettingsViewModel
Expand Down Expand Up @@ -100,6 +101,12 @@ fun AccountSettings(
}
}

uiState.loading.let{
if (it) {
ProgressIndicatorUi()
}
}

uiState.alert?.let { alert ->
when (alert) {
AccountSettingsAlert.LOGOUT -> {
Expand Down Expand Up @@ -133,7 +140,18 @@ fun AccountSettings(
dismissButtonText = stringResource(id = R.string.dismiss),
confirmButtonText = stringResource(id = R.string.withdraw),
onDismiss = { viewModel.hideAlert() },
onConfirm = { viewModel.deleteAccount() }
onConfirm = { viewModel.withdraw() }
)
}

AccountSettingsAlert.INTERNET_ERROR -> {
AlertDialogUi(
title = stringResource(id = R.string.internet_error_title),
text = stringResource(id = R.string.internet_error),
dismissButtonText = stringResource(id = R.string.dismiss),
confirmButtonText = stringResource(id = R.string.confirm),
onDismiss = { viewModel.hideAlert() },
onConfirm = { viewModel.hideAlert() }
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@ data class AuthVerifyEmailRequest(
@JsonClass(generateAdapter = true)
data class AuthResetPasswordRequest(
val password: String
)

@JsonClass(generateAdapter = true)
data class AuthRefreshRequest(
val refresh: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ class SessionManager @Inject constructor(
setValue(authToken)
}

// TODO: 나중에 SettingsScreen에서 이 logout() 호출
fun logout() {
fun clearAuthToken() {
setValue(null)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.example.speechbuddy.data.remote.models.AccessTokenDtoMapper
import com.example.speechbuddy.data.remote.models.AuthTokenDtoMapper
import com.example.speechbuddy.data.remote.models.ErrorResponseMapper
import com.example.speechbuddy.data.remote.requests.AuthLoginRequest
import com.example.speechbuddy.data.remote.requests.AuthRefreshRequest
import com.example.speechbuddy.data.remote.requests.AuthResetPasswordRequest
import com.example.speechbuddy.data.remote.requests.AuthSendCodeRequest
import com.example.speechbuddy.data.remote.requests.AuthSignupRequest
Expand All @@ -17,9 +18,12 @@ import com.example.speechbuddy.service.AuthService
import com.example.speechbuddy.utils.Resource
import com.example.speechbuddy.utils.ResponseCode
import com.example.speechbuddy.utils.ResponseHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import retrofit2.Response
import javax.inject.Inject
import javax.inject.Singleton
Expand Down Expand Up @@ -132,6 +136,32 @@ class AuthRepository @Inject constructor(
}
}

suspend fun logout(): Flow<Response<Void>> =
flow {
try {
val result = authService.logout(getAuthHeader(), AuthRefreshRequest(getRefreshToken()))
CoroutineScope(Dispatchers.IO).launch {
authTokenPrefsManager.clearAuthToken()
}
emit(result)
} catch (e: Exception) {
emit(noInternetResponse())
}
}

suspend fun withdraw(): Flow<Response<Void>> =
flow {
try {
val result = authService.withdraw(getAuthHeader(), AuthRefreshRequest(getRefreshToken()))
CoroutineScope(Dispatchers.IO).launch {
authTokenPrefsManager.clearAuthToken()
}
emit(result)
} catch (e: Exception) {
emit(noInternetResponse())
}
}

fun checkPreviousUser(): Flow<Resource<AuthToken>> {
return authTokenPrefsManager.preferencesFlow.map { authToken ->
if (!authToken.accessToken.isNullOrEmpty() && !authToken.refreshToken.isNullOrEmpty()) {
Expand All @@ -150,6 +180,10 @@ class AuthRepository @Inject constructor(
return "Bearer $accessToken"
}

private fun getRefreshToken(): String {
return sessionManager.cachedToken.value?.refreshToken!!
}

private fun <T> returnUnknownError(): Resource<T> {
return Resource.error(
"Unknown error", null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.example.speechbuddy.service
import com.example.speechbuddy.data.remote.models.AccessTokenDto
import com.example.speechbuddy.data.remote.models.AuthTokenDto
import com.example.speechbuddy.data.remote.requests.AuthLoginRequest
import com.example.speechbuddy.data.remote.requests.AuthRefreshRequest
import com.example.speechbuddy.data.remote.requests.AuthResetPasswordRequest
import com.example.speechbuddy.data.remote.requests.AuthSendCodeRequest
import com.example.speechbuddy.data.remote.requests.AuthSignupRequest
Expand Down Expand Up @@ -50,4 +51,16 @@ interface AuthService {
@Header("Authorization") header: String,
@Body resetPasswordRequest: AuthResetPasswordRequest
): Response<Void>

@POST("/user/logout/")
suspend fun logout(
@Header("Authorization") header: String,
@Body logoutRequest: AuthRefreshRequest
): Response<Void>

@POST("/user/withdraw")
suspend fun withdraw(
@Header("Authorization") header: String,
@Body withdrawRequest: AuthRefreshRequest
): Response<Void>
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ data class AccountSettingsUiState(
*/
val email: String = "[email protected]",
val nickname: String = "nickname",
val alert: AccountSettingsAlert? = null
val alert: AccountSettingsAlert? = null,
val loading: Boolean = false
)

enum class AccountSettingsAlert {
LOGOUT,
WITHDRAW,
WITHDRAW_PROCEED
WITHDRAW_PROCEED,
INTERNET_ERROR
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package com.example.speechbuddy.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.speechbuddy.domain.SessionManager
import com.example.speechbuddy.repository.AuthRepository
import com.example.speechbuddy.ui.models.AccountSettingsAlert
import com.example.speechbuddy.ui.models.AccountSettingsUiState
import com.example.speechbuddy.utils.ResponseCode
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
Expand All @@ -15,7 +17,8 @@ import javax.inject.Inject

@HiltViewModel
class AccountSettingsViewModel @Inject internal constructor(
private val repository: AuthRepository
private val repository: AuthRepository,
private val sessionManager: SessionManager
) : ViewModel() {

private val _uiState = MutableStateFlow(AccountSettingsUiState())
Expand All @@ -37,15 +40,49 @@ class AccountSettingsViewModel @Inject internal constructor(
}
}

private fun changeLoading() {
_uiState.update {
it.copy(loading = !it.loading)
}
}

fun logout() {
changeLoading()
viewModelScope.launch {
//repository.logout()
repository.logout().collect { result ->
when (result.code()) {
ResponseCode.SUCCESS.value -> {
changeLoading()
/* TODO: 디바이스에 저장돼 있는 유저 정보 초기화(토큰 말고) */
sessionManager.clearAuthToken()
}
ResponseCode.NO_INTERNET_CONNECTION.value -> {
changeLoading()
showAlert(AccountSettingsAlert.INTERNET_ERROR)
}
}
}
}
}

fun deleteAccount() {
fun withdraw() {
changeLoading()
viewModelScope.launch {
//repository.deleteAccount()
repository.logout().collect { result ->
when (result.code()) {
ResponseCode.SUCCESS.value -> {
changeLoading()
/* TODO: 디바이스에 저장돼 있는 유저 정보 초기화(토큰 말고) */
sessionManager.clearAuthToken()
}
ResponseCode.NO_INTERNET_CONNECTION.value -> {
changeLoading()
showAlert(AccountSettingsAlert.INTERNET_ERROR)
}
}
}
}
}


}

0 comments on commit 0bafd4c

Please sign in to comment.