From 2457a1f264a8e354fa724e9664ac53d84cfc31ad Mon Sep 17 00:00:00 2001 From: Son Myeongji Date: Mon, 13 May 2024 14:10:36 +0900 Subject: [PATCH 1/6] =?UTF-8?q?build:=20activity=20>=20fragment=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- feature/src/main/AndroidManifest.xml | 9 +- .../java/com/sopt/now/feature/MainActivity.kt | 9 ++ .../sopt/now/feature/auth/LoginActivity.kt | 101 ------------------ .../sopt/now/feature/auth/LoginFragment.kt | 72 +++++++++++++ .../{SignUpActivity.kt => SignUpFragment.kt} | 33 ++---- .../sopt/now/feature/mypage/MyPageFragment.kt | 6 +- ...{activity_login.xml => fragment_login.xml} | 0 ...ivity_sign_up.xml => fragment_sign_up.xml} | 0 feature/src/main/res/navigation/nav_graph.xml | 8 ++ 9 files changed, 99 insertions(+), 139 deletions(-) delete mode 100644 feature/src/main/java/com/sopt/now/feature/auth/LoginActivity.kt create mode 100644 feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt rename feature/src/main/java/com/sopt/now/feature/auth/{SignUpActivity.kt => SignUpFragment.kt} (60%) rename feature/src/main/res/layout/{activity_login.xml => fragment_login.xml} (100%) rename feature/src/main/res/layout/{activity_sign_up.xml => fragment_sign_up.xml} (100%) diff --git a/feature/src/main/AndroidManifest.xml b/feature/src/main/AndroidManifest.xml index 75bf52d..214feab 100644 --- a/feature/src/main/AndroidManifest.xml +++ b/feature/src/main/AndroidManifest.xml @@ -9,7 +9,7 @@ android:supportsRtl="true" android:theme="@style/Theme.NOWSOPTAndroid"> @@ -17,13 +17,6 @@ - - \ No newline at end of file diff --git a/feature/src/main/java/com/sopt/now/feature/MainActivity.kt b/feature/src/main/java/com/sopt/now/feature/MainActivity.kt index c922a13..d976673 100644 --- a/feature/src/main/java/com/sopt/now/feature/MainActivity.kt +++ b/feature/src/main/java/com/sopt/now/feature/MainActivity.kt @@ -1,6 +1,8 @@ package com.sopt.now.feature +import android.view.MotionEvent import android.view.View +import android.view.inputmethod.InputMethodManager import androidx.activity.OnBackPressedCallback import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope @@ -82,4 +84,11 @@ class MainActivity : BindingActivity(R.layout.activity_main snackBar(binding.root, getString(R.string.main_back_once_pressed_exit)) } } + + override fun dispatchTouchEvent(ev: MotionEvent): Boolean { + val imm: InputMethodManager = + getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager + imm.hideSoftInputFromWindow(currentFocus?.windowToken, 0) + return super.dispatchTouchEvent(ev) + } } diff --git a/feature/src/main/java/com/sopt/now/feature/auth/LoginActivity.kt b/feature/src/main/java/com/sopt/now/feature/auth/LoginActivity.kt deleted file mode 100644 index f119526..0000000 --- a/feature/src/main/java/com/sopt/now/feature/auth/LoginActivity.kt +++ /dev/null @@ -1,101 +0,0 @@ -package com.sopt.now.feature.auth - -import android.content.Intent -import android.view.MotionEvent -import android.view.inputmethod.InputMethodManager -import androidx.activity.result.ActivityResultLauncher -import androidx.activity.result.contract.ActivityResultContracts -import androidx.activity.viewModels -import androidx.lifecycle.flowWithLifecycle -import androidx.lifecycle.lifecycleScope -import com.sopt.now.core.base.BindingActivity -import com.sopt.now.core.util.context.snackBar -import com.sopt.now.core.util.context.toast -import com.sopt.now.core.util.intent.getSafeParcelable -import com.sopt.now.core.util.intent.navigateTo -import com.sopt.now.core.view.UiState -import com.sopt.now.feature.MainActivity -import com.sopt.now.feature.R -import com.sopt.now.feature.databinding.ActivityLoginBinding -import com.sopt.now.feature.model.User -import com.sopt.now.feature.util.KeyStorage -import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach - -@AndroidEntryPoint -class LoginActivity : BindingActivity(R.layout.activity_login) { - private lateinit var resultLauncher: ActivityResultLauncher - private val viewModel by viewModels() - - override fun initView() { - initAutoLoginStateObserve() - initRegisterResultLauncher() - initBtnClickListener() - initSignUpStateObserve() - } - - private fun initAutoLoginStateObserve() { - viewModel.autoLoginState.flowWithLifecycle(lifecycle).onEach { isAutoLogin -> - when (isAutoLogin) { - true -> navigateTo(this@LoginActivity) - false -> return@onEach - } - }.launchIn(lifecycleScope) - } - - private fun initRegisterResultLauncher() { - resultLauncher = - registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> - if (result.resultCode == RESULT_OK) { - result.data?.getSafeParcelable(name = KeyStorage.USER_INPUT) - ?.let { receivedUserInput -> - viewModel.setSavedUserInfo(receivedUserInput.toUserEntity()) - } - } - } - } - - private fun initBtnClickListener() { - initLoginBtnClickListener() - initSignUpBtnClickListener() - } - - private fun initLoginBtnClickListener() = with(binding) { - btnLogin.setOnClickListener { - viewModel.setLogin( - id = etLoginId.text.toString(), - pwd = etLoginPwd.text.toString() - ) - } - } - - private fun initSignUpBtnClickListener() { - binding.tvLoginSignUp.setOnClickListener { - val intent = Intent(this@LoginActivity, SignUpActivity::class.java) - resultLauncher.launch(intent) - } - } - - private fun initSignUpStateObserve() { - viewModel.loginState.flowWithLifecycle(lifecycle).onEach { state -> - when (state) { - is UiState.Success -> { - toast(getString(R.string.login_completed, getString(R.string.login))) - viewModel.saveCheckLoginSharedPreference(true) - navigateTo(this) - } - - is UiState.Failure -> snackBar(binding.root, state.errorMessage) - else -> Unit - } - }.launchIn(lifecycleScope) - } - - override fun dispatchTouchEvent(ev: MotionEvent): Boolean { - val imm: InputMethodManager = - getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager - imm.hideSoftInputFromWindow(currentFocus?.windowToken, 0) - return super.dispatchTouchEvent(ev) - } -} diff --git a/feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt b/feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt new file mode 100644 index 0000000..9b32c82 --- /dev/null +++ b/feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt @@ -0,0 +1,72 @@ +package com.sopt.now.feature.auth + +import androidx.fragment.app.viewModels +import androidx.lifecycle.flowWithLifecycle +import androidx.lifecycle.lifecycleScope +import com.sopt.now.core.base.BindingFragment +import com.sopt.now.core.util.fragment.snackBar +import com.sopt.now.core.util.fragment.toast +import com.sopt.now.core.view.UiState +import com.sopt.now.feature.R +import com.sopt.now.feature.databinding.FragmentLoginBinding +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach + +@AndroidEntryPoint +class LoginFragment : BindingFragment(R.layout.fragment_login) { + private val viewModel by viewModels() + + override fun initView() { + initAutoLoginStateObserve() + initBtnClickListener() + initSignUpStateObserve() + } + + private fun initAutoLoginStateObserve() { + viewModel.autoLoginState.flowWithLifecycle(lifecycle).onEach { isAutoLogin -> + when (isAutoLogin) { + true -> { + // TODO 홈 프레그먼트로 이동 + } + + false -> return@onEach + } + }.launchIn(lifecycleScope) + } + + private fun initBtnClickListener() { + initLoginBtnClickListener() + initSignUpBtnClickListener() + } + + private fun initLoginBtnClickListener() = with(binding) { + btnLogin.setOnClickListener { + viewModel.setLogin( + id = etLoginId.text.toString(), + pwd = etLoginPwd.text.toString() + ) + } + } + + private fun initSignUpBtnClickListener() { + binding.tvLoginSignUp.setOnClickListener { + // TODO 회원가입 프레그먼트로 이동 + } + } + + private fun initSignUpStateObserve() { + viewModel.loginState.flowWithLifecycle(lifecycle).onEach { state -> + when (state) { + is UiState.Success -> { + toast(getString(R.string.login_completed, getString(R.string.login))) + viewModel.saveCheckLoginSharedPreference(true) + // TODO 홈 프레그먼트로 이동 + } + + is UiState.Failure -> snackBar(binding.root, state.errorMessage) + else -> Unit + } + }.launchIn(lifecycleScope) + } +} diff --git a/feature/src/main/java/com/sopt/now/feature/auth/SignUpActivity.kt b/feature/src/main/java/com/sopt/now/feature/auth/SignUpFragment.kt similarity index 60% rename from feature/src/main/java/com/sopt/now/feature/auth/SignUpActivity.kt rename to feature/src/main/java/com/sopt/now/feature/auth/SignUpFragment.kt index 479b558..4780bab 100644 --- a/feature/src/main/java/com/sopt/now/feature/auth/SignUpActivity.kt +++ b/feature/src/main/java/com/sopt/now/feature/auth/SignUpFragment.kt @@ -1,25 +1,21 @@ package com.sopt.now.feature.auth -import android.content.Intent -import android.view.MotionEvent -import android.view.inputmethod.InputMethodManager -import androidx.activity.viewModels +import androidx.fragment.app.viewModels import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope -import com.sopt.now.core.base.BindingActivity -import com.sopt.now.core.util.context.snackBar -import com.sopt.now.core.util.context.toast +import com.sopt.now.core.base.BindingFragment +import com.sopt.now.core.util.fragment.snackBar +import com.sopt.now.core.util.fragment.toast import com.sopt.now.core.view.UiState import com.sopt.now.feature.R -import com.sopt.now.feature.databinding.ActivitySignUpBinding +import com.sopt.now.feature.databinding.FragmentSignUpBinding import com.sopt.now.feature.model.User -import com.sopt.now.feature.util.KeyStorage import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @AndroidEntryPoint -class SignUpActivity : BindingActivity(R.layout.activity_sign_up) { +class SignUpFragment : BindingFragment(R.layout.fragment_sign_up) { private val viewModel by viewModels() override fun initView() { @@ -50,7 +46,7 @@ class SignUpActivity : BindingActivity(R.layout.activity_ is UiState.Success -> { toast(getString(R.string.login_completed, getString(R.string.sign_up))) viewModel.saveUserInfoSharedPreference(state.data.toUserEntity()) - navigateToLoginActivity(state.data) + // TODO 로그인 프레그먼트로 이동 } is UiState.Failure -> { @@ -62,19 +58,4 @@ class SignUpActivity : BindingActivity(R.layout.activity_ }.launchIn(lifecycleScope) } - private fun navigateToLoginActivity(userInputData: User) { - Intent().apply { - putExtra(KeyStorage.USER_INPUT, userInputData) - }.also { - setResult(RESULT_OK, it) - finish() - } - } - - override fun dispatchTouchEvent(ev: MotionEvent): Boolean { - val imm: InputMethodManager = - getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager - imm.hideSoftInputFromWindow(currentFocus?.windowToken, 0) - return super.dispatchTouchEvent(ev) - } } diff --git a/feature/src/main/java/com/sopt/now/feature/mypage/MyPageFragment.kt b/feature/src/main/java/com/sopt/now/feature/mypage/MyPageFragment.kt index fdeb08f..919ae4b 100644 --- a/feature/src/main/java/com/sopt/now/feature/mypage/MyPageFragment.kt +++ b/feature/src/main/java/com/sopt/now/feature/mypage/MyPageFragment.kt @@ -3,9 +3,7 @@ package com.sopt.now.feature.mypage import androidx.fragment.app.viewModels import com.sopt.now.core.base.BindingFragment import com.sopt.now.core.util.fragment.toast -import com.sopt.now.core.util.intent.navigateTo import com.sopt.now.feature.R -import com.sopt.now.feature.auth.LoginActivity import com.sopt.now.feature.databinding.FragmentMyPageBinding import dagger.hilt.android.AndroidEntryPoint @@ -26,7 +24,7 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ binding.tvMainSignOut.setOnClickListener { viewModel.updateCheckLoginState(false) toast(getString(R.string.login_completed, getString(R.string.main_logout_under_bar))) - navigateTo(requireContext()) + // TODO 로그인 프레그먼트로 이동 } } @@ -39,7 +37,7 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ getString(R.string.main_clear_user_under_bar) ) ) - navigateTo(requireContext()) + // TODO 로그인 프레그먼트로 이동 } } diff --git a/feature/src/main/res/layout/activity_login.xml b/feature/src/main/res/layout/fragment_login.xml similarity index 100% rename from feature/src/main/res/layout/activity_login.xml rename to feature/src/main/res/layout/fragment_login.xml diff --git a/feature/src/main/res/layout/activity_sign_up.xml b/feature/src/main/res/layout/fragment_sign_up.xml similarity index 100% rename from feature/src/main/res/layout/activity_sign_up.xml rename to feature/src/main/res/layout/fragment_sign_up.xml diff --git a/feature/src/main/res/navigation/nav_graph.xml b/feature/src/main/res/navigation/nav_graph.xml index 71c194a..c2aaab4 100644 --- a/feature/src/main/res/navigation/nav_graph.xml +++ b/feature/src/main/res/navigation/nav_graph.xml @@ -32,4 +32,12 @@ android:name="com.sopt.now.feature.home.HomeDetailFragment" android:label="HomeDetailFragment" tools:layout="@layout/fragment_my_page" /> + + From b4bf82953522fe6ec764bbc8005a641d52a99b8e Mon Sep 17 00:00:00 2001 From: Son Myeongji Date: Mon, 13 May 2024 14:21:30 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20=ED=94=84=EB=9E=98=EA=B7=B8?= =?UTF-8?q?=EB=A8=BC=ED=8A=B8=20=EA=B0=84=20=EC=9D=B4=EB=8F=99=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sopt/now/feature/auth/LoginFragment.kt | 10 ++++------ .../java/com/sopt/now/feature/auth/SignUpFragment.kt | 3 ++- .../java/com/sopt/now/feature/mypage/MyPageFragment.kt | 5 +++-- feature/src/main/res/navigation/nav_graph.xml | 10 ++++++---- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt b/feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt index 9b32c82..acb66fd 100644 --- a/feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt +++ b/feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt @@ -3,6 +3,7 @@ package com.sopt.now.feature.auth import androidx.fragment.app.viewModels import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope +import androidx.navigation.fragment.findNavController import com.sopt.now.core.base.BindingFragment import com.sopt.now.core.util.fragment.snackBar import com.sopt.now.core.util.fragment.toast @@ -26,10 +27,7 @@ class LoginFragment : BindingFragment(R.layout.fragment_lo private fun initAutoLoginStateObserve() { viewModel.autoLoginState.flowWithLifecycle(lifecycle).onEach { isAutoLogin -> when (isAutoLogin) { - true -> { - // TODO 홈 프레그먼트로 이동 - } - + true -> findNavController().navigate(R.id.fragment_home) false -> return@onEach } }.launchIn(lifecycleScope) @@ -51,7 +49,7 @@ class LoginFragment : BindingFragment(R.layout.fragment_lo private fun initSignUpBtnClickListener() { binding.tvLoginSignUp.setOnClickListener { - // TODO 회원가입 프레그먼트로 이동 + findNavController().navigate(R.id.fragment_sign_up) } } @@ -61,7 +59,7 @@ class LoginFragment : BindingFragment(R.layout.fragment_lo is UiState.Success -> { toast(getString(R.string.login_completed, getString(R.string.login))) viewModel.saveCheckLoginSharedPreference(true) - // TODO 홈 프레그먼트로 이동 + findNavController().navigate(R.id.fragment_home) } is UiState.Failure -> snackBar(binding.root, state.errorMessage) diff --git a/feature/src/main/java/com/sopt/now/feature/auth/SignUpFragment.kt b/feature/src/main/java/com/sopt/now/feature/auth/SignUpFragment.kt index 4780bab..236e0a5 100644 --- a/feature/src/main/java/com/sopt/now/feature/auth/SignUpFragment.kt +++ b/feature/src/main/java/com/sopt/now/feature/auth/SignUpFragment.kt @@ -3,6 +3,7 @@ package com.sopt.now.feature.auth import androidx.fragment.app.viewModels import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope +import androidx.navigation.fragment.findNavController import com.sopt.now.core.base.BindingFragment import com.sopt.now.core.util.fragment.snackBar import com.sopt.now.core.util.fragment.toast @@ -46,7 +47,7 @@ class SignUpFragment : BindingFragment(R.layout.fragment_ is UiState.Success -> { toast(getString(R.string.login_completed, getString(R.string.sign_up))) viewModel.saveUserInfoSharedPreference(state.data.toUserEntity()) - // TODO 로그인 프레그먼트로 이동 + findNavController().navigate(R.id.fragment_login) } is UiState.Failure -> { diff --git a/feature/src/main/java/com/sopt/now/feature/mypage/MyPageFragment.kt b/feature/src/main/java/com/sopt/now/feature/mypage/MyPageFragment.kt index 919ae4b..1359cff 100644 --- a/feature/src/main/java/com/sopt/now/feature/mypage/MyPageFragment.kt +++ b/feature/src/main/java/com/sopt/now/feature/mypage/MyPageFragment.kt @@ -1,6 +1,7 @@ package com.sopt.now.feature.mypage import androidx.fragment.app.viewModels +import androidx.navigation.fragment.findNavController import com.sopt.now.core.base.BindingFragment import com.sopt.now.core.util.fragment.toast import com.sopt.now.feature.R @@ -24,7 +25,7 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ binding.tvMainSignOut.setOnClickListener { viewModel.updateCheckLoginState(false) toast(getString(R.string.login_completed, getString(R.string.main_logout_under_bar))) - // TODO 로그인 프레그먼트로 이동 + findNavController().navigate(R.id.fragment_login) } } @@ -37,7 +38,7 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ getString(R.string.main_clear_user_under_bar) ) ) - // TODO 로그인 프레그먼트로 이동 + findNavController().navigate(R.id.fragment_login) } } diff --git a/feature/src/main/res/navigation/nav_graph.xml b/feature/src/main/res/navigation/nav_graph.xml index c2aaab4..72873bd 100644 --- a/feature/src/main/res/navigation/nav_graph.xml +++ b/feature/src/main/res/navigation/nav_graph.xml @@ -33,11 +33,13 @@ android:label="HomeDetailFragment" tools:layout="@layout/fragment_my_page" /> + android:label="LoginFragment" + tools:layout="@layout/fragment_login" /> + android:label="SignUpFragment" + tools:layout="@layout/fragment_sign_up" /> From 74ff8bfd28150c2fd03b49ce1a1da3b2942aff78 Mon Sep 17 00:00:00 2001 From: Son Myeongji Date: Mon, 13 May 2024 14:35:15 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20=EC=95=B1=20=EC=A7=84=EC=9E=85=20?= =?UTF-8?q?=EC=8B=9C=20=EC=B4=88=EA=B8=B0=20=ED=94=84=EB=9E=98=EA=B7=B8?= =?UTF-8?q?=EB=A8=BC=ED=8A=B8=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- feature/src/main/java/com/sopt/now/feature/MainActivity.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/feature/src/main/java/com/sopt/now/feature/MainActivity.kt b/feature/src/main/java/com/sopt/now/feature/MainActivity.kt index d976673..f9e5afe 100644 --- a/feature/src/main/java/com/sopt/now/feature/MainActivity.kt +++ b/feature/src/main/java/com/sopt/now/feature/MainActivity.kt @@ -35,6 +35,7 @@ class MainActivity : BindingActivity(R.layout.activity_main (supportFragmentManager.findFragmentById(R.id.fcv_home) as NavHostFragment) .findNavController() binding.bnvHome.setupWithNavController(navController) + navController.navigate(R.id.fragment_login) doubleBackPressedOnHomeTab(navController) setBottomNavigationVisibility(navController) } From dadd41ae587e880e7ace41c00fc0804b84833e64 Mon Sep 17 00:00:00 2001 From: Son Myeongji Date: Thu, 16 May 2024 21:39:47 +0900 Subject: [PATCH 4/6] =?UTF-8?q?refactor:=20=EC=9E=90=EB=8F=99=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=97=AC=EB=B6=80=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sopt/now/feature/MainActivity.kt | 15 +++++++++ .../com/sopt/now/feature/MainViewModel.kt | 31 +++++++++++++++++++ .../sopt/now/feature/auth/LoginFragment.kt | 10 ------ .../sopt/now/feature/auth/LoginViewModel.kt | 26 ++++------------ feature/src/main/res/navigation/nav_graph.xml | 2 +- 5 files changed, 53 insertions(+), 31 deletions(-) create mode 100644 feature/src/main/java/com/sopt/now/feature/MainViewModel.kt diff --git a/feature/src/main/java/com/sopt/now/feature/MainActivity.kt b/feature/src/main/java/com/sopt/now/feature/MainActivity.kt index f9e5afe..27ac987 100644 --- a/feature/src/main/java/com/sopt/now/feature/MainActivity.kt +++ b/feature/src/main/java/com/sopt/now/feature/MainActivity.kt @@ -4,9 +4,11 @@ import android.view.MotionEvent import android.view.View import android.view.inputmethod.InputMethodManager import androidx.activity.OnBackPressedCallback +import androidx.activity.viewModels import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope import androidx.navigation.NavController +import androidx.navigation.Navigation import androidx.navigation.fragment.NavHostFragment import androidx.navigation.fragment.findNavController import androidx.navigation.ui.setupWithNavController @@ -25,9 +27,12 @@ class MainActivity : BindingActivity(R.layout.activity_main private var backPressedTime = 0L private val backPressedFlow = MutableSharedFlow() + private val viewModel: MainViewModel by viewModels() + override fun initView() { initMainBottomNavigation() initBackDoublePressed() + observeAutoLogin() } private fun initMainBottomNavigation() { @@ -86,6 +91,16 @@ class MainActivity : BindingActivity(R.layout.activity_main } } + private fun observeAutoLogin() { + viewModel.autoLoginState.flowWithLifecycle(lifecycle).onEach { isAutoLogin -> + val navController = Navigation.findNavController(this, R.id.fcv_home) + when (isAutoLogin) { + true -> navController.navigate(R.id.fragment_home) + false -> navController.navigate(R.id.fragment_login) + } + }.launchIn(lifecycleScope) + } + override fun dispatchTouchEvent(ev: MotionEvent): Boolean { val imm: InputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager diff --git a/feature/src/main/java/com/sopt/now/feature/MainViewModel.kt b/feature/src/main/java/com/sopt/now/feature/MainViewModel.kt new file mode 100644 index 0000000..83d4361 --- /dev/null +++ b/feature/src/main/java/com/sopt/now/feature/MainViewModel.kt @@ -0,0 +1,31 @@ +package com.sopt.now.feature + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.sopt.now.domain.usecase.sharedprefusecase.GetCheckLoginUseCase +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class MainViewModel @Inject constructor( + private val getCheckLoginUseCase: GetCheckLoginUseCase, +) : ViewModel() { + private val _autoLoginState = MutableStateFlow(false) + val autoLoginState: StateFlow get() = _autoLoginState.asStateFlow() + + init { + checkAutoLogin() + } + + private fun checkAutoLogin() { + viewModelScope.launch { + _autoLoginState.value = isAutoLogin() + } + } + + private fun isAutoLogin(): Boolean = getCheckLoginUseCase.invoke() +} \ No newline at end of file diff --git a/feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt b/feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt index acb66fd..b07817c 100644 --- a/feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt +++ b/feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt @@ -19,20 +19,10 @@ class LoginFragment : BindingFragment(R.layout.fragment_lo private val viewModel by viewModels() override fun initView() { - initAutoLoginStateObserve() initBtnClickListener() initSignUpStateObserve() } - private fun initAutoLoginStateObserve() { - viewModel.autoLoginState.flowWithLifecycle(lifecycle).onEach { isAutoLogin -> - when (isAutoLogin) { - true -> findNavController().navigate(R.id.fragment_home) - false -> return@onEach - } - }.launchIn(lifecycleScope) - } - private fun initBtnClickListener() { initLoginBtnClickListener() initSignUpBtnClickListener() diff --git a/feature/src/main/java/com/sopt/now/feature/auth/LoginViewModel.kt b/feature/src/main/java/com/sopt/now/feature/auth/LoginViewModel.kt index c2dd1a4..d4bb0ca 100644 --- a/feature/src/main/java/com/sopt/now/feature/auth/LoginViewModel.kt +++ b/feature/src/main/java/com/sopt/now/feature/auth/LoginViewModel.kt @@ -2,27 +2,24 @@ package com.sopt.now.feature.auth import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.sopt.now.feature.util.StringResources import com.sopt.now.core.view.UiState import com.sopt.now.domain.entity.UserEntity -import com.sopt.now.domain.usecase.sharedprefusecase.GetCheckLoginUseCase import com.sopt.now.domain.usecase.sharedprefusecase.GetUserInfoUseCase import com.sopt.now.domain.usecase.sharedprefusecase.SaveCheckLoginUseCase +import com.sopt.now.feature.util.StringResources import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asSharedFlow -import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class LoginViewModel @Inject constructor( private val getUserInfoUseCase: GetUserInfoUseCase, - private val getCheckLoginUseCase: GetCheckLoginUseCase, - private val saveCheckLoginUseCase: SaveCheckLoginUseCase + private val saveCheckLoginUseCase: SaveCheckLoginUseCase, ) : ViewModel() { private val _savedUserInfo = MutableStateFlow( UserEntity( @@ -37,32 +34,21 @@ class LoginViewModel @Inject constructor( private val _loginState = MutableSharedFlow>() val loginState: SharedFlow> get() = _loginState.asSharedFlow() - private val _autoLoginState = MutableStateFlow(false) - val autoLoginState: StateFlow get() = _autoLoginState.asStateFlow() - init { - checkAutoLogin() + getUserInfo() } - private fun checkAutoLogin() { + private fun getUserInfo() { viewModelScope.launch { - _autoLoginState.value = isAutoLogin() - if (!isAutoLogin()) { - _savedUserInfo.value = getUserInfoUseCase.invoke() - } + _savedUserInfo.value = getUserInfoUseCase.invoke() + } } - private fun isAutoLogin(): Boolean = getCheckLoginUseCase.invoke() - fun saveCheckLoginSharedPreference(input: Boolean) { saveCheckLoginUseCase.invoke(input) } - fun setSavedUserInfo(input: UserEntity) { - _savedUserInfo.value = input - } - fun setLogin(id: String, pwd: String) { checkLoginValidate(id, pwd) } diff --git a/feature/src/main/res/navigation/nav_graph.xml b/feature/src/main/res/navigation/nav_graph.xml index 72873bd..3a72f24 100644 --- a/feature/src/main/res/navigation/nav_graph.xml +++ b/feature/src/main/res/navigation/nav_graph.xml @@ -3,7 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/nav_graph" - app:startDestination="@id/fragment_home"> + app:startDestination="@id/fragment_login"> Date: Thu, 16 May 2024 21:50:15 +0900 Subject: [PATCH 5/6] =?UTF-8?q?refactor:=20=EC=8B=9C=EC=9E=91=EC=A0=90=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- feature/src/main/res/navigation/nav_graph.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/src/main/res/navigation/nav_graph.xml b/feature/src/main/res/navigation/nav_graph.xml index 3a72f24..72873bd 100644 --- a/feature/src/main/res/navigation/nav_graph.xml +++ b/feature/src/main/res/navigation/nav_graph.xml @@ -3,7 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/nav_graph" - app:startDestination="@id/fragment_login"> + app:startDestination="@id/fragment_home"> Date: Thu, 16 May 2024 22:41:52 +0900 Subject: [PATCH 6/6] =?UTF-8?q?refactor:=20=EB=B0=B1=EC=8A=A4=ED=83=9D=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sopt/now/feature/MainActivity.kt | 27 +++++++++++++++++++ .../sopt/now/feature/auth/LoginFragment.kt | 6 ++++- .../sopt/now/feature/mypage/MyPageFragment.kt | 14 ++++++++-- feature/src/main/res/navigation/nav_graph.xml | 13 ++++++--- 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/feature/src/main/java/com/sopt/now/feature/MainActivity.kt b/feature/src/main/java/com/sopt/now/feature/MainActivity.kt index 27ac987..047ec3b 100644 --- a/feature/src/main/java/com/sopt/now/feature/MainActivity.kt +++ b/feature/src/main/java/com/sopt/now/feature/MainActivity.kt @@ -1,5 +1,6 @@ package com.sopt.now.feature +import android.util.Log import android.view.MotionEvent import android.view.View import android.view.inputmethod.InputMethodManager @@ -107,4 +108,30 @@ class MainActivity : BindingActivity(R.layout.activity_main imm.hideSoftInputFromWindow(currentFocus?.windowToken, 0) return super.dispatchTouchEvent(ev) } + + override fun onResume() { + super.onResume() + + logFragmentStack() + } + + private fun logFragmentStack() { + val fragmentManager = + supportFragmentManager.findFragmentById(R.id.fcv_home) as NavHostFragment + + fragmentManager.childFragmentManager.addOnBackStackChangedListener { + if (fragmentManager.childFragmentManager.backStackEntryCount == 0) { + Log.i( + "backstack", + fragmentManager.childFragmentManager.backStackEntryCount.toString() + ) + + } else { + Log.i( + "backstack", + fragmentManager.childFragmentManager.backStackEntryCount.toString() + ) + } + } + } } diff --git a/feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt b/feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt index b07817c..c80701e 100644 --- a/feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt +++ b/feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt @@ -3,6 +3,7 @@ package com.sopt.now.feature.auth import androidx.fragment.app.viewModels import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope +import androidx.navigation.NavOptions import androidx.navigation.fragment.findNavController import com.sopt.now.core.base.BindingFragment import com.sopt.now.core.util.fragment.snackBar @@ -49,7 +50,10 @@ class LoginFragment : BindingFragment(R.layout.fragment_lo is UiState.Success -> { toast(getString(R.string.login_completed, getString(R.string.login))) viewModel.saveCheckLoginSharedPreference(true) - findNavController().navigate(R.id.fragment_home) + val navOptions = NavOptions.Builder() + .setPopUpTo(R.id.nav_graph, true) + .build() + findNavController().navigate(R.id.fragment_home, null, navOptions) } is UiState.Failure -> snackBar(binding.root, state.errorMessage) diff --git a/feature/src/main/java/com/sopt/now/feature/mypage/MyPageFragment.kt b/feature/src/main/java/com/sopt/now/feature/mypage/MyPageFragment.kt index 1359cff..df94e6e 100644 --- a/feature/src/main/java/com/sopt/now/feature/mypage/MyPageFragment.kt +++ b/feature/src/main/java/com/sopt/now/feature/mypage/MyPageFragment.kt @@ -1,6 +1,7 @@ package com.sopt.now.feature.mypage import androidx.fragment.app.viewModels +import androidx.navigation.NavOptions import androidx.navigation.fragment.findNavController import com.sopt.now.core.base.BindingFragment import com.sopt.now.core.util.fragment.toast @@ -25,7 +26,12 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ binding.tvMainSignOut.setOnClickListener { viewModel.updateCheckLoginState(false) toast(getString(R.string.login_completed, getString(R.string.main_logout_under_bar))) - findNavController().navigate(R.id.fragment_login) + + val navOptions = NavOptions.Builder() + .setPopUpTo(R.id.nav_graph, true) + .build() + + findNavController().navigate(R.id.fragment_login, null, navOptions) } } @@ -38,7 +44,11 @@ class MyPageFragment : BindingFragment(R.layout.fragment_ getString(R.string.main_clear_user_under_bar) ) ) - findNavController().navigate(R.id.fragment_login) + + val navOptions = NavOptions.Builder() + .setPopUpTo(R.id.nav_graph, true) + .build() + findNavController().navigate(R.id.fragment_login, null, navOptions) } } diff --git a/feature/src/main/res/navigation/nav_graph.xml b/feature/src/main/res/navigation/nav_graph.xml index 72873bd..42369a0 100644 --- a/feature/src/main/res/navigation/nav_graph.xml +++ b/feature/src/main/res/navigation/nav_graph.xml @@ -15,7 +15,9 @@ app:destination="@id/fragment_home_detail" /> + app:destination="@id/fragment_my_page" + app:popUpTo="@id/fragment_home" + app:popUpToInclusive="true" /> + tools:layout="@layout/fragment_my_page"> + + tools:layout="@layout/fragment_login"> + + tools:layout="@layout/fragment_sign_up"> +