Skip to content
Open
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
9 changes: 1 addition & 8 deletions feature/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,14 @@
android:supportsRtl="true"
android:theme="@style/Theme.NOWSOPTAndroid">
<activity
android:name="com.sopt.now.feature.auth.LoginActivity"
android:name="com.sopt.now.feature.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.sopt.now.feature.auth.SignUpActivity"
android:exported="false"
android:windowSoftInputMode="adjustResize" />
<activity
android:name="com.sopt.now.feature.MainActivity"
android:exported="false" />
</application>

</manifest>
52 changes: 52 additions & 0 deletions feature/src/main/java/com/sopt/now/feature/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package com.sopt.now.feature

import android.util.Log
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
Expand All @@ -23,16 +28,20 @@ class MainActivity : BindingActivity<ActivityMainBinding>(R.layout.activity_main
private var backPressedTime = 0L
private val backPressedFlow = MutableSharedFlow<Unit>()

private val viewModel: MainViewModel by viewModels()

override fun initView() {
initMainBottomNavigation()
initBackDoublePressed()
observeAutoLogin()
}

private fun initMainBottomNavigation() {
val navController =
(supportFragmentManager.findFragmentById(R.id.fcv_home) as NavHostFragment)
.findNavController()
binding.bnvHome.setupWithNavController(navController)
navController.navigate(R.id.fragment_login)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MainActivity에서 자동로그인 여부를 판단하고 로그인 화면으로 넘기는게 나을 것 같습니다!
지금은 무조건 로그인으로 넘어가고 로그인에서 자동로그인 여부를 판단하는데 불필요한 작업인것 같아서요!

로그인에서 옵저빙 하는 코드를 그대로 메인액티비티로 옮기시면 될것 같습니다!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

스택 관리에 조금 더 효율적일 것 같아서요!

doubleBackPressedOnHomeTab(navController)
setBottomNavigationVisibility(navController)
}
Expand Down Expand Up @@ -82,4 +91,47 @@ class MainActivity : BindingActivity<ActivityMainBinding>(R.layout.activity_main
snackBar(binding.root, getString(R.string.main_back_once_pressed_exit))
}
}

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
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()
)
}
}
}
}
31 changes: 31 additions & 0 deletions feature/src/main/java/com/sopt/now/feature/MainViewModel.kt
Original file line number Diff line number Diff line change
@@ -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<Boolean>(false)
val autoLoginState: StateFlow<Boolean> get() = _autoLoginState.asStateFlow()

init {
checkAutoLogin()
}

private fun checkAutoLogin() {
viewModelScope.launch {
_autoLoginState.value = isAutoLogin()
}
}

private fun isAutoLogin(): Boolean = getCheckLoginUseCase.invoke()
}
101 changes: 0 additions & 101 deletions feature/src/main/java/com/sopt/now/feature/auth/LoginActivity.kt

This file was deleted.

64 changes: 64 additions & 0 deletions feature/src/main/java/com/sopt/now/feature/auth/LoginFragment.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
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
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<FragmentLoginBinding>(R.layout.fragment_login) {
private val viewModel by viewModels<LoginViewModel>()

override fun initView() {
initBtnClickListener()
initSignUpStateObserve()
}

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 {
findNavController().navigate(R.id.fragment_sign_up)
}
}

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)
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)
else -> Unit
}
}.launchIn(lifecycleScope)
}
}
26 changes: 6 additions & 20 deletions feature/src/main/java/com/sopt/now/feature/auth/LoginViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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>(
UserEntity(
Expand All @@ -37,32 +34,21 @@ class LoginViewModel @Inject constructor(
private val _loginState = MutableSharedFlow<UiState<UserEntity>>()
val loginState: SharedFlow<UiState<UserEntity>> get() = _loginState.asSharedFlow()

private val _autoLoginState = MutableStateFlow<Boolean>(false)
val autoLoginState: StateFlow<Boolean> 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)
}
Expand Down
Loading