From 712117a7f0160a66319dfe2d946667f1abf6c54d Mon Sep 17 00:00:00 2001 From: HyunWoo Lee Date: Thu, 2 Jan 2025 01:07:07 +0900 Subject: [PATCH] =?UTF-8?q?[#1012]=20MyPageActivity=EC=97=90=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/mypage/mypage/MyPageActivity.kt | 75 ++++++------- .../feature/mypage/mypage/MyPageViewModel.kt | 103 ------------------ 2 files changed, 35 insertions(+), 143 deletions(-) delete mode 100644 feature/mypage/src/main/java/org/sopt/official/feature/mypage/mypage/MyPageViewModel.kt diff --git a/feature/mypage/src/main/java/org/sopt/official/feature/mypage/mypage/MyPageActivity.kt b/feature/mypage/src/main/java/org/sopt/official/feature/mypage/mypage/MyPageActivity.kt index 1013c96a4..c3e297439 100644 --- a/feature/mypage/src/main/java/org/sopt/official/feature/mypage/mypage/MyPageActivity.kt +++ b/feature/mypage/src/main/java/org/sopt/official/feature/mypage/mypage/MyPageActivity.kt @@ -30,7 +30,6 @@ import android.net.Uri import android.os.Bundle import android.provider.Settings import androidx.activity.compose.setContent -import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column @@ -42,15 +41,10 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp -import androidx.lifecycle.compose.LocalLifecycleOwner -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import androidx.lifecycle.flowWithLifecycle import dagger.hilt.android.AndroidEntryPoint import kotlinx.collections.immutable.persistentListOf import org.sopt.official.auth.model.UserActiveState @@ -60,8 +54,15 @@ import org.sopt.official.designsystem.SoptTheme import org.sopt.official.feature.mypage.component.MyPageDialog import org.sopt.official.feature.mypage.component.MyPageSection import org.sopt.official.feature.mypage.component.MyPageTopBar +import org.sopt.official.feature.mypage.di.authRepository +import org.sopt.official.feature.mypage.di.stampRepository import org.sopt.official.feature.mypage.model.MyPageUiModel -import org.sopt.official.feature.mypage.model.MyPageUiState +import org.sopt.official.feature.mypage.mypage.state.ClearSoptamp +import org.sopt.official.feature.mypage.mypage.state.CloseDialog +import org.sopt.official.feature.mypage.mypage.state.Logout +import org.sopt.official.feature.mypage.mypage.state.MyPageDialogState +import org.sopt.official.feature.mypage.mypage.state.ResetSoptamp +import org.sopt.official.feature.mypage.mypage.state.rememberMyPageUiState import org.sopt.official.feature.mypage.signout.SignOutActivity import org.sopt.official.feature.mypage.soptamp.ui.AdjustSentenceActivity import org.sopt.official.feature.mypage.web.WebUrlConstant @@ -70,7 +71,6 @@ import javax.inject.Inject @AndroidEntryPoint class MyPageActivity : AppCompatActivity() { - private val viewModel by viewModels() private val args by serializableExtra(Argument(UserActiveState.UNAUTHENTICATED)) @Inject @@ -80,11 +80,14 @@ class MyPageActivity : AppCompatActivity() { super.onCreate(savedInstanceState) setContent { SoptTheme { + val uiState = rememberMyPageUiState( + userActiveState = args?.userActiveState ?: UserActiveState.UNAUTHENTICATED, + authRepository = authRepository, + stampRepository = stampRepository, + onRestartApp = { startActivity(navigatorProvider.getAuthActivityIntent()) } + ) val context = LocalContext.current - val lifecycleOwner = LocalLifecycleOwner.current - val myPageState by viewModel.state.collectAsStateWithLifecycle() - val myPageAction by viewModel.action.collectAsStateWithLifecycle() val scrollState = rememberScrollState() val serviceSectionItems = remember { @@ -136,7 +139,9 @@ class MyPageActivity : AppCompatActivity() { ), MyPageUiModel.MyPageItem( title = "스탬프 초기화", - onItemClick = { viewModel.showDialogState(MyPageAction.CLEAR_SOPTAMP) } + onItemClick = { + uiState.onEventSink(ClearSoptamp) + } ) ) } @@ -146,7 +151,9 @@ class MyPageActivity : AppCompatActivity() { MyPageUiModel.Header(title = "기타"), MyPageUiModel.MyPageItem( title = "로그아웃", - onItemClick = { viewModel.showDialogState(MyPageAction.LOGOUT) } + onItemClick = { + uiState.onEventSink(Logout) + } ), MyPageUiModel.MyPageItem( title = "탈퇴하기", @@ -167,19 +174,6 @@ class MyPageActivity : AppCompatActivity() { ) } - LaunchedEffect(Unit) { - args?.userActiveState?.let { - viewModel.setUserActiveState(it) - } - } - - LaunchedEffect(viewModel.finish, lifecycleOwner) { - viewModel.finish.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle) - .collect { - startActivity(navigatorProvider.getAuthActivityIntent()) - } - } - Scaffold( modifier = Modifier .background(SoptTheme.colors.background) @@ -201,8 +195,8 @@ class MyPageActivity : AppCompatActivity() { Spacer(modifier = Modifier.height(20.dp)) MyPageSection(items = serviceSectionItems) Spacer(modifier = Modifier.height(16.dp)) - when (myPageState) { - is MyPageUiState.Authenticated -> { + when (uiState.user) { + UserActiveState.ACTIVE, UserActiveState.INACTIVE -> { MyPageSection(items = notificationSectionItems) Spacer(modifier = Modifier.height(16.dp)) MyPageSection(items = soptampSectionItems) @@ -210,20 +204,19 @@ class MyPageActivity : AppCompatActivity() { MyPageSection(items = etcSectionItems) } - is MyPageUiState.UnAuthenticated -> { + UserActiveState.UNAUTHENTICATED -> { MyPageSection(items = etcLoginSectionItems) } - - is MyPageUiState.UnInitialized -> {} } Spacer(modifier = Modifier.height(32.dp)) } - if (myPageAction != null) { + + if (uiState.dialogState != MyPageDialogState.CLEAR) { ShowMyPageDialog( - action = myPageAction ?: return@Scaffold, - onDismissRequest = viewModel::closeDialog, - onClearSoptampClick = viewModel::resetSoptamp, - onLogoutClick = viewModel::logOut + dialogState = uiState.dialogState, + onDismissRequest = { uiState.onEventSink(CloseDialog) }, + onClearSoptampClick = { uiState.onEventSink(ResetSoptamp) }, + onLogoutClick = { uiState.onEventSink(Logout) } ) } } @@ -245,13 +238,13 @@ class MyPageActivity : AppCompatActivity() { @Composable private fun ShowMyPageDialog( - action: MyPageAction, + dialogState: MyPageDialogState, onDismissRequest: () -> Unit, onClearSoptampClick: () -> Unit, onLogoutClick: () -> Unit ) { - when (action) { - MyPageAction.CLEAR_SOPTAMP -> { + when (dialogState) { + MyPageDialogState.CLEAR_SOPTAMP -> { MyPageDialog( onDismissRequest = onDismissRequest, title = "미션을 초기화 하실건가요?", @@ -262,7 +255,7 @@ private fun ShowMyPageDialog( ) } - MyPageAction.LOGOUT -> { + MyPageDialogState.LOGOUT -> { MyPageDialog( onDismissRequest = onDismissRequest, title = "로그아웃", @@ -272,5 +265,7 @@ private fun ShowMyPageDialog( onPositiveButtonClick = onLogoutClick ) } + + else -> {} } } diff --git a/feature/mypage/src/main/java/org/sopt/official/feature/mypage/mypage/MyPageViewModel.kt b/feature/mypage/src/main/java/org/sopt/official/feature/mypage/mypage/MyPageViewModel.kt deleted file mode 100644 index 09148e37a..000000000 --- a/feature/mypage/src/main/java/org/sopt/official/feature/mypage/mypage/MyPageViewModel.kt +++ /dev/null @@ -1,103 +0,0 @@ -/* - * MIT License - * Copyright 2023-2024 SOPT - Shout Our Passion Together - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.sopt.official.feature.mypage.mypage - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.google.firebase.messaging.FirebaseMessaging -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.receiveAsFlow -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch -import kotlinx.coroutines.tasks.await -import org.sopt.official.auth.model.UserActiveState -import org.sopt.official.auth.repository.AuthRepository -import org.sopt.official.domain.soptamp.repository.StampRepository -import org.sopt.official.feature.mypage.model.MyPageUiState -import timber.log.Timber -import javax.inject.Inject - -enum class MyPageAction { - CLEAR_SOPTAMP, LOGOUT -} - -@HiltViewModel -class MyPageViewModel @Inject constructor( - private val authRepository: AuthRepository, - private val stampRepository: StampRepository, -) : ViewModel() { - - private val _state: MutableStateFlow = MutableStateFlow(MyPageUiState.UnInitialized) - val state: StateFlow = _state.asStateFlow() - - private val _action = MutableStateFlow(null) - val action: StateFlow = _action.asStateFlow() - - private val _finish = Channel() - val finish = _finish.receiveAsFlow() - - fun setUserActiveState(activeState: UserActiveState) { - _state.update { - if (activeState == UserActiveState.UNAUTHENTICATED) MyPageUiState.UnAuthenticated - else MyPageUiState.Authenticated(activeState) - } - } - - fun logOut() { - viewModelScope.launch { - runCatching { - FirebaseMessaging.getInstance().token.await() - }.onSuccess { - authRepository.logout(it) - .onSuccess { - authRepository.clearLocalData() - _finish.send(Unit) - }.onFailure { error -> Timber.e(error) } - }.onFailure { - Timber.e(it) - } - } - } - - fun resetSoptamp() { - viewModelScope.launch { - stampRepository.deleteAllStamps() - .onSuccess { closeDialog() } - .onFailure { Timber.e(it) } - } - } - - fun showDialogState(action: MyPageAction) { - _action.update { action } - } - - fun closeDialog() { - _action.update { null } - } -}