From da9318ac8bd69bafda327b887c99afd8be3eec97 Mon Sep 17 00:00:00 2001 From: wjchoi96 Date: Sun, 26 Nov 2023 23:24:21 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:TOP-87=20core:navigation=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 1 + core/compose-ui/build.gradle.kts | 4 +- core/navigation/.gitignore | 1 + core/navigation/build.gradle.kts | 39 +++++++++++++++++++ core/navigation/consumer-rules.pro | 0 core/navigation/proguard-rules.pro | 21 ++++++++++ .../navigation/ExampleInstrumentedTest.kt | 24 ++++++++++++ core/navigation/src/main/AndroidManifest.xml | 4 ++ .../tht/core/navigation/ExampleUnitTest.kt | 17 ++++++++ feature/chat/build.gradle.kts | 1 + feature/heart/build.gradle.kts | 1 + feature/setting/build.gradle.kts | 1 + feature/signin/build.gradle.kts | 1 + feature/tohot/build.gradle.kts | 1 + settings.gradle.kts | 1 + 15 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 core/navigation/.gitignore create mode 100644 core/navigation/build.gradle.kts create mode 100644 core/navigation/consumer-rules.pro create mode 100644 core/navigation/proguard-rules.pro create mode 100644 core/navigation/src/androidTest/java/tht/core/navigation/ExampleInstrumentedTest.kt create mode 100644 core/navigation/src/main/AndroidManifest.xml create mode 100644 core/navigation/src/test/java/tht/core/navigation/ExampleUnitTest.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1644cc71..fbca2f6d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -53,6 +53,7 @@ android { } dependencies { + implementation(project(":core:navigation")) implementation(project(":core:ui")) implementation(project(":domain")) implementation(project(":data")) diff --git a/core/compose-ui/build.gradle.kts b/core/compose-ui/build.gradle.kts index 4ea9e48a..f568b6ec 100644 --- a/core/compose-ui/build.gradle.kts +++ b/core/compose-ui/build.gradle.kts @@ -5,10 +5,10 @@ plugins { android { namespace = "com.example.compose_ui" - compileSdk = 33 + compileSdk = rootProject.ext.get("compileSdk") as Int defaultConfig { - minSdk = 24 + minSdk = rootProject.ext.get("minSdkVersion") as Int testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles("consumer-rules.pro") diff --git a/core/navigation/.gitignore b/core/navigation/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/core/navigation/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/core/navigation/build.gradle.kts b/core/navigation/build.gradle.kts new file mode 100644 index 00000000..7c43da8a --- /dev/null +++ b/core/navigation/build.gradle.kts @@ -0,0 +1,39 @@ +plugins { + id("com.android.library") + id("org.jetbrains.kotlin.android") +} + +android { + namespace = "tht.core.navigation" + compileSdk = rootProject.ext.get("compileSdk") as Int + + defaultConfig { + minSdk = rootProject.ext.get("minSdkVersion") as Int + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } +} + +dependencies { + implementation("androidx.core:core-ktx:1.9.0") + implementation("androidx.appcompat:appcompat:1.6.1") + implementation("com.google.android.material:material:1.8.0") + testImplementation("junit:junit:4.13.2") + androidTestImplementation("androidx.test.ext:junit:1.1.5") + androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") +} diff --git a/core/navigation/consumer-rules.pro b/core/navigation/consumer-rules.pro new file mode 100644 index 00000000..e69de29b diff --git a/core/navigation/proguard-rules.pro b/core/navigation/proguard-rules.pro new file mode 100644 index 00000000..481bb434 --- /dev/null +++ b/core/navigation/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/core/navigation/src/androidTest/java/tht/core/navigation/ExampleInstrumentedTest.kt b/core/navigation/src/androidTest/java/tht/core/navigation/ExampleInstrumentedTest.kt new file mode 100644 index 00000000..e4009a1a --- /dev/null +++ b/core/navigation/src/androidTest/java/tht/core/navigation/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package tht.core.navigation + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("tht.core.navigation.test", appContext.packageName) + } +} diff --git a/core/navigation/src/main/AndroidManifest.xml b/core/navigation/src/main/AndroidManifest.xml new file mode 100644 index 00000000..8bdb7e14 --- /dev/null +++ b/core/navigation/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + diff --git a/core/navigation/src/test/java/tht/core/navigation/ExampleUnitTest.kt b/core/navigation/src/test/java/tht/core/navigation/ExampleUnitTest.kt new file mode 100644 index 00000000..8ce45b77 --- /dev/null +++ b/core/navigation/src/test/java/tht/core/navigation/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package tht.core.navigation + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} diff --git a/feature/chat/build.gradle.kts b/feature/chat/build.gradle.kts index 2f807277..eb0e03dd 100644 --- a/feature/chat/build.gradle.kts +++ b/feature/chat/build.gradle.kts @@ -45,6 +45,7 @@ android { } dependencies { + implementation(project(":core:navigation")) implementation(project(":core:ui")) implementation(project(":core:compose-ui")) implementation(project(":domain")) diff --git a/feature/heart/build.gradle.kts b/feature/heart/build.gradle.kts index 2a0a9bf2..00a6f5fa 100644 --- a/feature/heart/build.gradle.kts +++ b/feature/heart/build.gradle.kts @@ -34,6 +34,7 @@ android { } dependencies { + implementation(project(":core:navigation")) implementation(project(":core:ui")) implementation(project(":domain")) diff --git a/feature/setting/build.gradle.kts b/feature/setting/build.gradle.kts index 653bf2e6..0708156b 100644 --- a/feature/setting/build.gradle.kts +++ b/feature/setting/build.gradle.kts @@ -34,6 +34,7 @@ android { } dependencies { + implementation(project(":core:navigation")) implementation(project(":core:ui")) implementation(project(":domain")) diff --git a/feature/signin/build.gradle.kts b/feature/signin/build.gradle.kts index 18058f27..6d6352bb 100644 --- a/feature/signin/build.gradle.kts +++ b/feature/signin/build.gradle.kts @@ -42,6 +42,7 @@ android { } dependencies { + implementation(project(":core:navigation")) implementation(project(":core:ui")) implementation(project(":domain")) diff --git a/feature/tohot/build.gradle.kts b/feature/tohot/build.gradle.kts index fe7dd7bf..445d4897 100644 --- a/feature/tohot/build.gradle.kts +++ b/feature/tohot/build.gradle.kts @@ -41,6 +41,7 @@ android { } dependencies { + implementation(project(":core:navigation")) implementation(project(":core:ui")) implementation(project(":core:compose-ui")) implementation(project(":domain")) diff --git a/settings.gradle.kts b/settings.gradle.kts index c23b6bb7..94466d7c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -37,3 +37,4 @@ include(":feature:signin") include(":core") include(":core:ui") include(":core:compose-ui") +include(":core:navigation") From 5b353583efc3db2988e1dde1d135008160aa80b6 Mon Sep 17 00:00:00 2001 From: wjchoi96 Date: Sun, 26 Nov 2023 23:33:20 +0900 Subject: [PATCH 2/2] =?UTF-8?q?feat:TOP-87=20=EB=AA=A8=EB=93=88=EA=B0=84?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99=EC=9D=84=20core:navigation=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=EC=9D=84=20=ED=86=B5=ED=95=B4=20=EC=A7=84=ED=96=89?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - feature모듈은 core:navigation 모듈에 의존해서 모듈간 이동 진행 - core:navigation 모듈에 feature별 navigation interface를 정의, 각 feature에서 구현체 구현 - app 모듈에 navigation di 코드 작성 - 불필요한 코드 제거 --- app/src/main/java/com/tht/tht/HomeActivity.kt | 10 ++++++- .../main/java/com/tht/tht/SplashActivity.kt | 28 ++++++++----------- .../main/java/com/tht/tht/SplashViewModel.kt | 11 -------- .../tht/tht/navigation/HomeNavigationImpl.kt | 13 +++++++++ .../tht/tht/navigation/NavigationModule.kt | 25 +++++++++++++++++ .../tht/core/navigation/HomeNavigation.kt | 7 +++++ .../tht/core/navigation/SignupNavigation.kt | 7 +++++ .../tht/core/navigation/ToHotNavigation.kt | 10 +++++++ .../signin/navigation/SignupNavigationImpl.kt | 12 ++++++++ .../signin/prelogin/PreloginActivity.kt | 8 ------ .../signin/signup/SignupRootActivity.kt | 8 ++++-- .../tohot/navigation/ToHotNavigationImpl.kt | 25 +++++++++++++++++ 12 files changed, 125 insertions(+), 39 deletions(-) create mode 100644 app/src/main/java/com/tht/tht/navigation/HomeNavigationImpl.kt create mode 100644 app/src/main/java/com/tht/tht/navigation/NavigationModule.kt create mode 100644 core/navigation/src/main/java/tht/core/navigation/HomeNavigation.kt create mode 100644 core/navigation/src/main/java/tht/core/navigation/SignupNavigation.kt create mode 100644 core/navigation/src/main/java/tht/core/navigation/ToHotNavigation.kt create mode 100644 feature/signin/src/main/java/tht/feature/signin/navigation/SignupNavigationImpl.kt create mode 100644 feature/tohot/src/main/java/tht/feature/tohot/navigation/ToHotNavigationImpl.kt diff --git a/app/src/main/java/com/tht/tht/HomeActivity.kt b/app/src/main/java/com/tht/tht/HomeActivity.kt index 5c7ce9e6..34159a29 100644 --- a/app/src/main/java/com/tht/tht/HomeActivity.kt +++ b/app/src/main/java/com/tht/tht/HomeActivity.kt @@ -12,6 +12,7 @@ import androidx.lifecycle.repeatOnLifecycle import com.tht.tht.databinding.ActivityHomeBinding import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch +import tht.core.navigation.ToHotNavigation import tht.core.ui.base.BaseActivity import tht.core.ui.base.FragmentNavigator import tht.core.ui.delegate.viewBinding @@ -20,6 +21,7 @@ import tht.feature.chat.ChatFragment import tht.feature.heart.HeartFragment import tht.feature.setting.MyFragment import tht.feature.tohot.tohot.fragment.ToHotFragment +import javax.inject.Inject @SuppressLint("CommitTransaction") @AndroidEntryPoint @@ -28,6 +30,9 @@ class HomeActivity : BaseActivity(), Fragmen override val vm by viewModels() override val binding by viewBinding(ActivityHomeBinding::inflate) + @Inject + lateinit var toHotNavigation: ToHotNavigation + override fun initViews() { initNavigationBar() } @@ -42,7 +47,10 @@ class HomeActivity : BaseActivity(), Fragmen binding.bnvHome.setOnItemSelectedListener { item -> when (item.itemId) { R.id.menu_tohot -> { - showFragment(ToHotFragment.TAG) + toHotNavigation.navigateToHot( + supportFragmentManager, + R.id.fragment_container + ) true } R.id.menu_heart -> { diff --git a/app/src/main/java/com/tht/tht/SplashActivity.kt b/app/src/main/java/com/tht/tht/SplashActivity.kt index f1f57488..77dafd5b 100644 --- a/app/src/main/java/com/tht/tht/SplashActivity.kt +++ b/app/src/main/java/com/tht/tht/SplashActivity.kt @@ -3,17 +3,16 @@ package com.tht.tht import android.animation.Animator import android.annotation.SuppressLint import android.os.Bundle -import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen -import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import com.tht.tht.databinding.ActivitySplashBinding import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch +import tht.core.navigation.SignupNavigation import tht.core.ui.delegate.viewBinding -import tht.feature.signin.prelogin.PreloginActivity +import javax.inject.Inject @SuppressLint("CustomSplashScreen") @AndroidEntryPoint @@ -22,6 +21,12 @@ class SplashActivity : AppCompatActivity() { private val viewModel: SplashViewModel by viewModels() private val binding: ActivitySplashBinding by viewBinding(ActivitySplashBinding::inflate) + @Inject + lateinit var signupNavigation: SignupNavigation + + @Inject + lateinit var homeNavigation: SignupNavigation + override fun onCreate(savedInstanceState: Bundle?) { installSplashScreen() super.onCreate(savedInstanceState) @@ -46,27 +51,16 @@ class SplashActivity : AppCompatActivity() { } private fun observeViewModel() { - val signupResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { - binding.lottieView.isVisible = false - when (it.resultCode) { - RESULT_OK -> viewModel.signupSuccessEvent() - else -> viewModel.signupCancelEvent() - } - } - lifecycleScope.launch { viewModel.sideEffect.collect { when (it) { is SplashSideEffect.Signup -> { - signupResult.launch(PreloginActivity.getIntent(this@SplashActivity)) - } - - is SplashSideEffect.Home -> { - startActivity(HomeActivity.newIntent(this@SplashActivity)) + signupNavigation.navigatePreLogin(this@SplashActivity) finish() } - is SplashSideEffect.Cancel -> { + is SplashSideEffect.Home -> { + homeNavigation.navigatePreLogin(this@SplashActivity) finish() } } diff --git a/app/src/main/java/com/tht/tht/SplashViewModel.kt b/app/src/main/java/com/tht/tht/SplashViewModel.kt index 0767434f..2c0cae37 100644 --- a/app/src/main/java/com/tht/tht/SplashViewModel.kt +++ b/app/src/main/java/com/tht/tht/SplashViewModel.kt @@ -21,10 +21,6 @@ class SplashViewModel @Inject constructor( checkAutoLogin() } - fun signupSuccessEvent() { - checkAutoLogin() - } - private fun checkAutoLogin() { viewModelScope.launch { fetchThtTokenUseCase() @@ -36,16 +32,9 @@ class SplashViewModel @Inject constructor( } } } - - fun signupCancelEvent() { - viewModelScope.launch { - _sideEffect.emit(SplashSideEffect.Cancel) - } - } } sealed class SplashSideEffect { object Signup : SplashSideEffect() object Home : SplashSideEffect() - object Cancel : SplashSideEffect() } diff --git a/app/src/main/java/com/tht/tht/navigation/HomeNavigationImpl.kt b/app/src/main/java/com/tht/tht/navigation/HomeNavigationImpl.kt new file mode 100644 index 00000000..2b525b8c --- /dev/null +++ b/app/src/main/java/com/tht/tht/navigation/HomeNavigationImpl.kt @@ -0,0 +1,13 @@ +package com.tht.tht.navigation + +import android.content.Context +import com.tht.tht.HomeActivity +import tht.core.navigation.HomeNavigation +import javax.inject.Inject + +class HomeNavigationImpl @Inject constructor() : HomeNavigation { + + override fun navigateHome(context: Context) { + context.startActivity(HomeActivity.newIntent(context)) + } +} diff --git a/app/src/main/java/com/tht/tht/navigation/NavigationModule.kt b/app/src/main/java/com/tht/tht/navigation/NavigationModule.kt new file mode 100644 index 00000000..42fc16f7 --- /dev/null +++ b/app/src/main/java/com/tht/tht/navigation/NavigationModule.kt @@ -0,0 +1,25 @@ +package com.tht.tht.navigation + +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import tht.core.navigation.HomeNavigation +import tht.core.navigation.SignupNavigation +import tht.core.navigation.ToHotNavigation +import tht.feature.signin.navigation.SignupNavigationImpl +import tht.feature.tohot.navigation.ToHotNavigationImpl + +@Module +@InstallIn(SingletonComponent::class) +abstract class NavigationModule { + + @Binds + abstract fun bindHomeNavigation(impl: HomeNavigationImpl): HomeNavigation + + @Binds + abstract fun bindSignupNavigation(impl: SignupNavigationImpl): SignupNavigation + + @Binds + abstract fun bindToHotNavigation(impl: ToHotNavigationImpl): ToHotNavigation +} diff --git a/core/navigation/src/main/java/tht/core/navigation/HomeNavigation.kt b/core/navigation/src/main/java/tht/core/navigation/HomeNavigation.kt new file mode 100644 index 00000000..a729068e --- /dev/null +++ b/core/navigation/src/main/java/tht/core/navigation/HomeNavigation.kt @@ -0,0 +1,7 @@ +package tht.core.navigation + +import android.content.Context + +interface HomeNavigation { + fun navigateHome(context: Context) +} diff --git a/core/navigation/src/main/java/tht/core/navigation/SignupNavigation.kt b/core/navigation/src/main/java/tht/core/navigation/SignupNavigation.kt new file mode 100644 index 00000000..4f81ae07 --- /dev/null +++ b/core/navigation/src/main/java/tht/core/navigation/SignupNavigation.kt @@ -0,0 +1,7 @@ +package tht.core.navigation + +import android.content.Context + +interface SignupNavigation { + fun navigatePreLogin(context: Context) +} diff --git a/core/navigation/src/main/java/tht/core/navigation/ToHotNavigation.kt b/core/navigation/src/main/java/tht/core/navigation/ToHotNavigation.kt new file mode 100644 index 00000000..9f40e311 --- /dev/null +++ b/core/navigation/src/main/java/tht/core/navigation/ToHotNavigation.kt @@ -0,0 +1,10 @@ +package tht.core.navigation + +import androidx.fragment.app.FragmentManager + +interface ToHotNavigation { + fun navigateToHot( + fragmentManager: FragmentManager, + fragmentContainerResourceId: Int + ) +} diff --git a/feature/signin/src/main/java/tht/feature/signin/navigation/SignupNavigationImpl.kt b/feature/signin/src/main/java/tht/feature/signin/navigation/SignupNavigationImpl.kt new file mode 100644 index 00000000..58e1b2c9 --- /dev/null +++ b/feature/signin/src/main/java/tht/feature/signin/navigation/SignupNavigationImpl.kt @@ -0,0 +1,12 @@ +package tht.feature.signin.navigation + +import android.content.Context +import tht.core.navigation.SignupNavigation +import tht.feature.signin.prelogin.PreloginActivity +import javax.inject.Inject + +class SignupNavigationImpl @Inject constructor() : SignupNavigation { + override fun navigatePreLogin(context: Context) { + context.startActivity(PreloginActivity.getIntent(context)) + } +} diff --git a/feature/signin/src/main/java/tht/feature/signin/prelogin/PreloginActivity.kt b/feature/signin/src/main/java/tht/feature/signin/prelogin/PreloginActivity.kt index 2365f7a1..768487e4 100644 --- a/feature/signin/src/main/java/tht/feature/signin/prelogin/PreloginActivity.kt +++ b/feature/signin/src/main/java/tht/feature/signin/prelogin/PreloginActivity.kt @@ -2,7 +2,6 @@ package tht.feature.signin.prelogin import android.content.Context import android.content.Intent -import android.util.Log import androidx.activity.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -30,13 +29,6 @@ class PreloginActivity : BaseStateActivity { - startActivity(PreloginActivity.getIntent(this@SignupRootActivity)) + homeNavigation.navigateHome(this@SignupRootActivity) finish() } is SignupRootViewModel.SignupRootSideEffect.ShowToast -> { diff --git a/feature/tohot/src/main/java/tht/feature/tohot/navigation/ToHotNavigationImpl.kt b/feature/tohot/src/main/java/tht/feature/tohot/navigation/ToHotNavigationImpl.kt new file mode 100644 index 00000000..43c2b904 --- /dev/null +++ b/feature/tohot/src/main/java/tht/feature/tohot/navigation/ToHotNavigationImpl.kt @@ -0,0 +1,25 @@ +package tht.feature.tohot.navigation + +import androidx.fragment.app.FragmentManager +import tht.core.navigation.ToHotNavigation +import tht.feature.tohot.tohot.fragment.ToHotFragment +import javax.inject.Inject + +class ToHotNavigationImpl @Inject constructor() : ToHotNavigation { + override fun navigateToHot( + fragmentManager: FragmentManager, + fragmentContainerResourceId: Int + ) { + val foundFragment = fragmentManager.findFragmentByTag(ToHotFragment.TAG) + fragmentManager.fragments.forEach { fm -> + fragmentManager.beginTransaction().hide(fm).commitAllowingStateLoss() + } + foundFragment?.let { + fragmentManager.beginTransaction().show(it).commitAllowingStateLoss() + } ?: run { + fragmentManager.beginTransaction() + .add(fragmentContainerResourceId, ToHotFragment.newInstance(), ToHotFragment.TAG) + .commitAllowingStateLoss() + } + } +}