diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 000000000..ab481915a
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,9 @@
+# CLAUDE.md
+
+## Code Style Rules
+
+### No Inline Imports (FQCN 직접 사용 금지)
+- 클래스를 사용할 때 반드시 상단에 `import` 문을 선언하고, 코드 본문에서는 단순 클래스명만 사용할 것
+- `android.app.Activity`처럼 FQCN(Fully Qualified Class Name)을 코드 본문에 직접 작성하지 않을 것
+- Bad: `(context as? android.app.Activity)?.finish()`
+- Good: `import android.app.Activity` 후 `(context as? Activity)?.finish()`
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 7fb3c640f..869408005 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -81,6 +81,7 @@ dependencies {
implementation(projects.core.firebaseCrashlytics)
implementation(projects.core.firebaseMessaging)
implementation(projects.core.composeLocals)
+ implementation(projects.core.designsystem)
implementation(projects.core.work)
implementation(projects.data.domain)
implementation(projects.data.club)
@@ -90,6 +91,9 @@ dependencies {
implementation(projects.data.notification)
implementation(projects.data.place)
implementation(projects.domain.navigation)
+ implementation(projects.core.navigation)
+ implementation(libs.navigation3.runtime)
+ implementation(libs.navigation3.ui)
implementation(projects.feature.editDepartments)
implementation(projects.feature.editSubscription)
implementation(projects.feature.feedback)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b06a0f8e0..1992fda16 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -26,6 +26,10 @@
android:usesCleartextTraffic="true"
tools:replace="icon, label">
+
+
+
+ override fun onCreate(savedInstanceState: android.os.Bundle?) {
+ super.onCreate(savedInstanceState)
+ enableEdgeToEdge()
+ setContent {
+ KuringCompositionLocalProvider {
+ KuringTheme {
+ val backStack = rememberNavBackStack(SplashKey)
+ NavDisplay(
+ backStack = backStack,
+ onBack = { if (backStack.removeLastOrNull() == null) finish() },
+ entryProvider = entryProvider {
+ entryBuilders.forEach { builder ->
+ with(builder) { provide() }
+ }
+ }
+ )
+ }
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/ku_stacks/ku_ring/di/NavigationModule.kt b/app/src/main/java/com/ku_stacks/ku_ring/di/NavigationModule.kt
new file mode 100644
index 000000000..a8cd9c6bc
--- /dev/null
+++ b/app/src/main/java/com/ku_stacks/ku_ring/di/NavigationModule.kt
@@ -0,0 +1,14 @@
+package com.ku_stacks.ku_ring.di
+
+import com.ku_stacks.ku_ring.navigation.EntryBuilderProvider
+import dagger.Module
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import dagger.multibindings.Multibinds
+
+@Module
+@InstallIn(SingletonComponent::class)
+abstract class NavigationModule {
+ @Multibinds
+ abstract fun bindEntryBuilderProviders(): Set
+}
diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts
index ee11c0ebe..10dadc5fa 100644
--- a/build-logic/build.gradle.kts
+++ b/build-logic/build.gradle.kts
@@ -73,6 +73,10 @@ gradlePlugin {
id = "com.ku_stacks.ku_ring.buildlogic.primitive.common-android"
implementationClass = "com.ku_stacks.ku_ring.buildlogic.primitive.CommonAndroidPlugin"
}
+ register("com.ku_stacks.ku_ring.buildlogic.primitive.Navigation3Plugin") {
+ id = "com.ku_stacks.ku_ring.buildlogic.primitive.navigation3"
+ implementationClass = "com.ku_stacks.ku_ring.buildlogic.primitive.Navigation3Plugin"
+ }
register("com.ku_stacks.ku_ring.buildlogic.primitive.AndroidTestPlugin") {
id = "com.ku_stacks.ku_ring.buildlogic.primitive.android-test"
implementationClass = "com.ku_stacks.ku_ring.buildlogic.primitive.AndroidTestPlugin"
diff --git a/build-logic/src/main/kotlin/com/ku_stacks/ku_ring/buildlogic/primitive/Navigation3Plugin.kt b/build-logic/src/main/kotlin/com/ku_stacks/ku_ring/buildlogic/primitive/Navigation3Plugin.kt
new file mode 100644
index 000000000..7427cd03b
--- /dev/null
+++ b/build-logic/src/main/kotlin/com/ku_stacks/ku_ring/buildlogic/primitive/Navigation3Plugin.kt
@@ -0,0 +1,19 @@
+package com.ku_stacks.ku_ring.buildlogic.primitive
+
+import com.ku_stacks.ku_ring.buildlogic.dsl.implementation
+import com.ku_stacks.ku_ring.buildlogic.dsl.library
+import com.ku_stacks.ku_ring.buildlogic.dsl.libs
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.dependencies
+
+class Navigation3Plugin : Plugin {
+ override fun apply(target: Project) =
+ with(target) {
+ dependencies {
+ implementation(libs.library("navigation3-runtime"))
+ implementation(libs.library("navigation3-ui"))
+ implementation(libs.library("lifecycle-viewmodel-navigation3"))
+ }
+ }
+}
diff --git a/core/navigation/.gitignore b/core/navigation/.gitignore
new file mode 100644
index 000000000..796b96d1c
--- /dev/null
+++ b/core/navigation/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/core/navigation/build.gradle.kts b/core/navigation/build.gradle.kts
new file mode 100644
index 000000000..30a928573
--- /dev/null
+++ b/core/navigation/build.gradle.kts
@@ -0,0 +1,13 @@
+import com.ku_stacks.ku_ring.buildlogic.dsl.setNameSpace
+
+plugins {
+ kuring("feature")
+}
+
+android {
+ setNameSpace("core.navigation")
+}
+
+dependencies {
+ api(libs.navigation3.runtime)
+}
diff --git a/core/navigation/consumer-rules.pro b/core/navigation/consumer-rules.pro
new file mode 100644
index 000000000..2ce9674dc
--- /dev/null
+++ b/core/navigation/consumer-rules.pro
@@ -0,0 +1,3 @@
+# Keep all @Serializable NavKey implementations for Navigation 3 back stack serialization
+-keep @kotlinx.serialization.Serializable class * implements androidx.navigation3.runtime.NavKey { *; }
+-keepnames @kotlinx.serialization.Serializable class * implements androidx.navigation3.runtime.NavKey
diff --git a/core/navigation/src/main/java/com/ku_stacks/ku_ring/navigation/EntryBuilderProvider.kt b/core/navigation/src/main/java/com/ku_stacks/ku_ring/navigation/EntryBuilderProvider.kt
new file mode 100644
index 000000000..0a2f09a06
--- /dev/null
+++ b/core/navigation/src/main/java/com/ku_stacks/ku_ring/navigation/EntryBuilderProvider.kt
@@ -0,0 +1,8 @@
+package com.ku_stacks.ku_ring.navigation
+
+import androidx.navigation3.runtime.EntryProviderScope
+import androidx.navigation3.runtime.NavKey
+
+interface EntryBuilderProvider {
+ fun EntryProviderScope.provide()
+}
diff --git a/core/navigation/src/main/java/com/ku_stacks/ku_ring/navigation/keys/AppLifecycleKeys.kt b/core/navigation/src/main/java/com/ku_stacks/ku_ring/navigation/keys/AppLifecycleKeys.kt
new file mode 100644
index 000000000..05436fbb3
--- /dev/null
+++ b/core/navigation/src/main/java/com/ku_stacks/ku_ring/navigation/keys/AppLifecycleKeys.kt
@@ -0,0 +1,8 @@
+package com.ku_stacks.ku_ring.navigation.keys
+
+import androidx.navigation3.runtime.NavKey
+import kotlinx.serialization.Serializable
+
+@Serializable data object SplashKey : NavKey
+@Serializable data object OnboardingKey : NavKey
+@Serializable data class AuthFlowKey(val entryPoint: String) : NavKey
diff --git a/core/navigation/src/main/java/com/ku_stacks/ku_ring/navigation/keys/ContentDetailKeys.kt b/core/navigation/src/main/java/com/ku_stacks/ku_ring/navigation/keys/ContentDetailKeys.kt
new file mode 100644
index 000000000..2dc392b29
--- /dev/null
+++ b/core/navigation/src/main/java/com/ku_stacks/ku_ring/navigation/keys/ContentDetailKeys.kt
@@ -0,0 +1,18 @@
+package com.ku_stacks.ku_ring.navigation.keys
+
+import androidx.navigation3.runtime.NavKey
+import kotlinx.serialization.Serializable
+
+@Serializable data class NoticeWebKey(
+ val url: String,
+ val articleId: String,
+ val id: String,
+ val category: String,
+ val subject: String,
+) : NavKey
+
+@Serializable data class NotionViewKey(val url: String) : NavKey
+
+@Serializable data object ClubOnboardingKey : NavKey
+@Serializable data class ClubDetailKey(val clubId: Int) : NavKey
+@Serializable data object ClubSubscriptionKey : NavKey
diff --git a/core/navigation/src/main/java/com/ku_stacks/ku_ring/navigation/keys/MainNavigationKeys.kt b/core/navigation/src/main/java/com/ku_stacks/ku_ring/navigation/keys/MainNavigationKeys.kt
new file mode 100644
index 000000000..c8583ae44
--- /dev/null
+++ b/core/navigation/src/main/java/com/ku_stacks/ku_ring/navigation/keys/MainNavigationKeys.kt
@@ -0,0 +1,9 @@
+package com.ku_stacks.ku_ring.navigation.keys
+
+import androidx.navigation3.runtime.NavKey
+import kotlinx.serialization.Serializable
+
+@Serializable data class MainHubKey(val startTab: String = "Notice") : NavKey
+@Serializable data object ArchiveKey : NavKey
+@Serializable data object SearchKey : NavKey
+@Serializable data object OpenSourceKey : NavKey
diff --git a/core/navigation/src/main/java/com/ku_stacks/ku_ring/navigation/keys/UtilityScreenKeys.kt b/core/navigation/src/main/java/com/ku_stacks/ku_ring/navigation/keys/UtilityScreenKeys.kt
new file mode 100644
index 000000000..8eb2834ea
--- /dev/null
+++ b/core/navigation/src/main/java/com/ku_stacks/ku_ring/navigation/keys/UtilityScreenKeys.kt
@@ -0,0 +1,11 @@
+package com.ku_stacks.ku_ring.navigation.keys
+
+import androidx.navigation3.runtime.NavKey
+import kotlinx.serialization.Serializable
+
+@Serializable data object FeedbackKey : NavKey
+@Serializable data object EditSubscriptionKey : NavKey
+@Serializable data object EditDepartmentsKey : NavKey
+@Serializable data object NotificationKey : NavKey
+@Serializable data object LibrarySeatKey : NavKey
+@Serializable data object KuringBotKey : NavKey
diff --git a/domain/navigation/consumer-rules.pro b/domain/navigation/consumer-rules.pro
deleted file mode 100644
index e69de29bb..000000000
diff --git a/feature/club/build.gradle.kts b/feature/club/build.gradle.kts
index 7e4a7c6de..e3065a127 100644
--- a/feature/club/build.gradle.kts
+++ b/feature/club/build.gradle.kts
@@ -12,6 +12,7 @@ android {
}
dependencies {
+ implementation(projects.core.navigation)
implementation(projects.core.designsystem)
implementation(projects.core.preferences)
implementation(projects.core.ui)
diff --git a/feature/club/src/main/java/com/ku_stacks/ku_ring/club/detail/ClubDetailActivity.kt b/feature/club/src/main/java/com/ku_stacks/ku_ring/club/detail/ClubDetailActivity.kt
index 013410952..72b9f88ad 100644
--- a/feature/club/src/main/java/com/ku_stacks/ku_ring/club/detail/ClubDetailActivity.kt
+++ b/feature/club/src/main/java/com/ku_stacks/ku_ring/club/detail/ClubDetailActivity.kt
@@ -4,15 +4,6 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
-import androidx.activity.compose.setContent
-import androidx.activity.enableEdgeToEdge
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.safeDrawingPadding
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.LocalContext
-import com.ku_stacks.ku_ring.designsystem.kuringtheme.KuringTheme
-import com.ku_stacks.ku_ring.util.navigateToExternalBrowser
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
@@ -20,22 +11,9 @@ class ClubDetailActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- enableEdgeToEdge()
-
- setContent {
- KuringTheme {
- val context = LocalContext.current
-
- ClubDetailScreen(
- onBack = ::finish,
- onMoveToRecruitmentLink = context::navigateToExternalBrowser,
- modifier = Modifier
- .background(KuringTheme.colors.background)
- .safeDrawingPadding()
- .fillMaxSize(),
- )
- }
- }
+ val intent = Intent().setClassName(this, "com.ku_stacks.ku_ring.HostActivity")
+ startActivity(intent)
+ finish()
}
companion object {
diff --git a/feature/club/src/main/java/com/ku_stacks/ku_ring/club/detail/ClubDetailEntryBuilder.kt b/feature/club/src/main/java/com/ku_stacks/ku_ring/club/detail/ClubDetailEntryBuilder.kt
new file mode 100644
index 000000000..5317e7f50
--- /dev/null
+++ b/feature/club/src/main/java/com/ku_stacks/ku_ring/club/detail/ClubDetailEntryBuilder.kt
@@ -0,0 +1,43 @@
+package com.ku_stacks.ku_ring.club.detail
+
+import android.app.Activity
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.safeDrawingPadding
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.navigation3.runtime.EntryProviderScope
+import androidx.navigation3.runtime.NavKey
+import com.ku_stacks.ku_ring.designsystem.kuringtheme.KuringTheme
+import com.ku_stacks.ku_ring.navigation.EntryBuilderProvider
+import com.ku_stacks.ku_ring.navigation.keys.ClubDetailKey
+import com.ku_stacks.ku_ring.util.navigateToExternalBrowser
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import dagger.multibindings.IntoSet
+
+class ClubDetailEntryBuilder : EntryBuilderProvider {
+ override fun EntryProviderScope.provide() {
+ entry { key ->
+ val context = LocalContext.current
+ ClubDetailScreen(
+ onBack = { (context as? Activity)?.finish() },
+ onMoveToRecruitmentLink = context::navigateToExternalBrowser,
+ modifier = Modifier
+ .background(KuringTheme.colors.background)
+ .safeDrawingPadding()
+ .fillMaxSize(),
+ )
+ }
+ }
+}
+
+@Module
+@InstallIn(SingletonComponent::class)
+object ClubDetailEntryBuilderModule {
+ @Provides
+ @IntoSet
+ fun provideClubDetailEntryBuilder(): EntryBuilderProvider = ClubDetailEntryBuilder()
+}
diff --git a/feature/club/src/main/java/com/ku_stacks/ku_ring/club/onboarding/ClubOnboardingActivity.kt b/feature/club/src/main/java/com/ku_stacks/ku_ring/club/onboarding/ClubOnboardingActivity.kt
index 193909a9e..40791a82a 100644
--- a/feature/club/src/main/java/com/ku_stacks/ku_ring/club/onboarding/ClubOnboardingActivity.kt
+++ b/feature/club/src/main/java/com/ku_stacks/ku_ring/club/onboarding/ClubOnboardingActivity.kt
@@ -4,23 +4,15 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
-import androidx.activity.compose.setContent
-import androidx.activity.enableEdgeToEdge
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.ui.Modifier
-import com.ku_stacks.ku_ring.designsystem.kuringtheme.KuringTheme
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class ClubOnboardingActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- enableEdgeToEdge()
- setContent {
- KuringTheme {
- ClubOnboardingScreen(onClose = ::finish, modifier = Modifier.fillMaxSize())
- }
- }
+ val intent = Intent().setClassName(this, "com.ku_stacks.ku_ring.HostActivity")
+ startActivity(intent)
+ finish()
}
companion object {
diff --git a/feature/club/src/main/java/com/ku_stacks/ku_ring/club/onboarding/ClubOnboardingEntryBuilder.kt b/feature/club/src/main/java/com/ku_stacks/ku_ring/club/onboarding/ClubOnboardingEntryBuilder.kt
new file mode 100644
index 000000000..52e9a5616
--- /dev/null
+++ b/feature/club/src/main/java/com/ku_stacks/ku_ring/club/onboarding/ClubOnboardingEntryBuilder.kt
@@ -0,0 +1,35 @@
+package com.ku_stacks.ku_ring.club.onboarding
+
+import android.app.Activity
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.navigation3.runtime.EntryProviderScope
+import androidx.navigation3.runtime.NavKey
+import com.ku_stacks.ku_ring.navigation.EntryBuilderProvider
+import com.ku_stacks.ku_ring.navigation.keys.ClubOnboardingKey
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import dagger.multibindings.IntoSet
+
+class ClubOnboardingEntryBuilder : EntryBuilderProvider {
+ override fun EntryProviderScope.provide() {
+ entry {
+ val context = LocalContext.current
+ ClubOnboardingScreen(
+ onClose = { (context as? Activity)?.finish() },
+ modifier = Modifier.fillMaxSize(),
+ )
+ }
+ }
+}
+
+@Module
+@InstallIn(SingletonComponent::class)
+object ClubOnboardingEntryBuilderModule {
+ @Provides
+ @IntoSet
+ fun provideClubOnboardingEntryBuilder(): EntryBuilderProvider = ClubOnboardingEntryBuilder()
+}
diff --git a/feature/club/src/main/java/com/ku_stacks/ku_ring/club/subscription/ClubSubscriptionActivity.kt b/feature/club/src/main/java/com/ku_stacks/ku_ring/club/subscription/ClubSubscriptionActivity.kt
index e45941529..3e025c078 100644
--- a/feature/club/src/main/java/com/ku_stacks/ku_ring/club/subscription/ClubSubscriptionActivity.kt
+++ b/feature/club/src/main/java/com/ku_stacks/ku_ring/club/subscription/ClubSubscriptionActivity.kt
@@ -4,26 +4,15 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
-import androidx.activity.compose.setContent
-import androidx.activity.enableEdgeToEdge
-import com.ku_stacks.ku_ring.designsystem.kuringtheme.KuringTheme
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class ClubSubscriptionActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- enableEdgeToEdge()
- setContent {
- KuringTheme {
- ClubSubscriptionScreen(
- onNavigateUp = ::finish,
- onNavigateToClubDetail = { clubId ->
- // TODO: 동아리 상세 화면으로 이동하는 로직 구현
- },
- )
- }
- }
+ val intent = Intent().setClassName(this, "com.ku_stacks.ku_ring.HostActivity")
+ startActivity(intent)
+ finish()
}
companion object {
diff --git a/feature/club/src/main/java/com/ku_stacks/ku_ring/club/subscription/ClubSubscriptionEntryBuilder.kt b/feature/club/src/main/java/com/ku_stacks/ku_ring/club/subscription/ClubSubscriptionEntryBuilder.kt
new file mode 100644
index 000000000..4a620db5f
--- /dev/null
+++ b/feature/club/src/main/java/com/ku_stacks/ku_ring/club/subscription/ClubSubscriptionEntryBuilder.kt
@@ -0,0 +1,33 @@
+package com.ku_stacks.ku_ring.club.subscription
+
+import android.app.Activity
+import androidx.compose.ui.platform.LocalContext
+import androidx.navigation3.runtime.EntryProviderScope
+import androidx.navigation3.runtime.NavKey
+import com.ku_stacks.ku_ring.navigation.EntryBuilderProvider
+import com.ku_stacks.ku_ring.navigation.keys.ClubSubscriptionKey
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import dagger.multibindings.IntoSet
+
+class ClubSubscriptionEntryBuilder : EntryBuilderProvider {
+ override fun EntryProviderScope.provide() {
+ entry {
+ val context = LocalContext.current
+ ClubSubscriptionScreen(
+ onNavigateUp = { (context as? Activity)?.finish() },
+ onNavigateToClubDetail = { },
+ )
+ }
+ }
+}
+
+@Module
+@InstallIn(SingletonComponent::class)
+object ClubSubscriptionEntryBuilderModule {
+ @Provides
+ @IntoSet
+ fun provideClubSubscriptionEntryBuilder(): EntryBuilderProvider = ClubSubscriptionEntryBuilder()
+}
diff --git a/feature/edit_departments/build.gradle.kts b/feature/edit_departments/build.gradle.kts
index edf2ed8f8..b003b377f 100644
--- a/feature/edit_departments/build.gradle.kts
+++ b/feature/edit_departments/build.gradle.kts
@@ -10,6 +10,7 @@ android {
}
dependencies {
+ implementation(projects.core.navigation)
implementation(projects.core.util)
implementation(projects.core.ui)
implementation(projects.core.designsystem)
diff --git a/feature/edit_departments/src/main/java/com/ku_stacks/ku_ring/edit_departments/EditDepartmentsActivity.kt b/feature/edit_departments/src/main/java/com/ku_stacks/ku_ring/edit_departments/EditDepartmentsActivity.kt
index a81d5f7fe..38de63331 100644
--- a/feature/edit_departments/src/main/java/com/ku_stacks/ku_ring/edit_departments/EditDepartmentsActivity.kt
+++ b/feature/edit_departments/src/main/java/com/ku_stacks/ku_ring/edit_departments/EditDepartmentsActivity.kt
@@ -4,42 +4,20 @@ import android.app.Activity
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
-import androidx.activity.compose.setContent
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.ui.Modifier
-import com.ku_stacks.ku_ring.designsystem.kuringtheme.KuringTheme
-import com.ku_stacks.ku_ring.edit_departments.compose.EditDepartmentsScreen
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class EditDepartmentsActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContent {
- KuringTheme {
- EditDepartmentsScreen(
- onClose = ::finish,
- modifier = Modifier
- .fillMaxSize()
- .background(KuringTheme.colors.background),
- )
- }
- }
- }
-
- override fun finish() {
- super.finish()
- overridePendingTransition(R.anim.anim_slide_left_enter, R.anim.anim_slide_left_exit)
+ val intent = Intent().setClassName(this, "com.ku_stacks.ku_ring.HostActivity")
+ startActivity(intent)
+ finish()
}
companion object {
fun start(activity: Activity) {
- activity.apply {
- val intent = Intent(this, EditDepartmentsActivity::class.java)
- startActivity(intent)
- overridePendingTransition(R.anim.anim_slide_right_enter, R.anim.anim_stay_exit)
- }
+ activity.startActivity(Intent(activity, EditDepartmentsActivity::class.java))
}
}
-}
\ No newline at end of file
+}
diff --git a/feature/edit_departments/src/main/java/com/ku_stacks/ku_ring/edit_departments/EditDepartmentsEntryBuilder.kt b/feature/edit_departments/src/main/java/com/ku_stacks/ku_ring/edit_departments/EditDepartmentsEntryBuilder.kt
new file mode 100644
index 000000000..3204c80ac
--- /dev/null
+++ b/feature/edit_departments/src/main/java/com/ku_stacks/ku_ring/edit_departments/EditDepartmentsEntryBuilder.kt
@@ -0,0 +1,40 @@
+package com.ku_stacks.ku_ring.edit_departments
+
+import android.app.Activity
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.navigation3.runtime.EntryProviderScope
+import androidx.navigation3.runtime.NavKey
+import com.ku_stacks.ku_ring.designsystem.kuringtheme.KuringTheme
+import com.ku_stacks.ku_ring.edit_departments.compose.EditDepartmentsScreen
+import com.ku_stacks.ku_ring.navigation.EntryBuilderProvider
+import com.ku_stacks.ku_ring.navigation.keys.EditDepartmentsKey
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import dagger.multibindings.IntoSet
+
+class EditDepartmentsEntryBuilder : EntryBuilderProvider {
+ override fun EntryProviderScope.provide() {
+ entry {
+ val context = LocalContext.current
+ EditDepartmentsScreen(
+ onClose = { (context as? Activity)?.finish() },
+ modifier = Modifier
+ .fillMaxSize()
+ .background(KuringTheme.colors.background),
+ )
+ }
+ }
+}
+
+@Module
+@InstallIn(SingletonComponent::class)
+object EditDepartmentsEntryBuilderModule {
+ @Provides
+ @IntoSet
+ fun provideEditDepartmentsEntryBuilder(): EntryBuilderProvider = EditDepartmentsEntryBuilder()
+}
diff --git a/feature/edit_subscription/build.gradle.kts b/feature/edit_subscription/build.gradle.kts
index 7d322faa7..151fcc4f9 100644
--- a/feature/edit_subscription/build.gradle.kts
+++ b/feature/edit_subscription/build.gradle.kts
@@ -8,6 +8,7 @@ android {
}
dependencies {
+ implementation(projects.core.navigation)
implementation(projects.core.util)
implementation(projects.core.designsystem)
implementation(projects.core.ui)
diff --git a/feature/edit_subscription/src/main/java/com/ku_stacks/ku_ring/edit_subscription/EditSubscriptionActivity.kt b/feature/edit_subscription/src/main/java/com/ku_stacks/ku_ring/edit_subscription/EditSubscriptionActivity.kt
index 614367e38..64f558c22 100644
--- a/feature/edit_subscription/src/main/java/com/ku_stacks/ku_ring/edit_subscription/EditSubscriptionActivity.kt
+++ b/feature/edit_subscription/src/main/java/com/ku_stacks/ku_ring/edit_subscription/EditSubscriptionActivity.kt
@@ -3,14 +3,7 @@ package com.ku_stacks.ku_ring.edit_subscription
import android.app.Activity
import android.content.Intent
import android.os.Bundle
-import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.ui.Modifier
-import com.ku_stacks.ku_ring.designsystem.kuringtheme.KuringTheme
-import com.ku_stacks.ku_ring.edit_subscription.compose.EditSubscriptionScreen
-import com.ku_stacks.ku_ring.compose.locals.KuringCompositionLocalProvider
-import com.ku_stacks.ku_ring.compose.locals.LocalNavigator
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
@@ -18,30 +11,9 @@ class EditSubscriptionActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
-
- setContent {
- KuringCompositionLocalProvider {
- val navigator = LocalNavigator.current
- KuringTheme {
- EditSubscriptionScreen(
- onNavigateToBack = ::finish,
- onAddDepartmentButtonClick = {
- navigator.navigateToEditSubscribedDepartment(this)
- },
- onFinish = {
- setResult(RESULT_OK)
- finish()
- },
- modifier = Modifier.fillMaxSize(),
- )
- }
- }
- }
- }
-
- override fun finish() {
- super.finish()
- overridePendingTransition(R.anim.anim_slide_left_enter, R.anim.anim_slide_left_exit)
+ val intent = Intent().setClassName(this, "com.ku_stacks.ku_ring.HostActivity")
+ startActivity(intent)
+ finish()
}
companion object {
diff --git a/feature/edit_subscription/src/main/java/com/ku_stacks/ku_ring/edit_subscription/EditSubscriptionEntryBuilder.kt b/feature/edit_subscription/src/main/java/com/ku_stacks/ku_ring/edit_subscription/EditSubscriptionEntryBuilder.kt
new file mode 100644
index 000000000..c4dc53cef
--- /dev/null
+++ b/feature/edit_subscription/src/main/java/com/ku_stacks/ku_ring/edit_subscription/EditSubscriptionEntryBuilder.kt
@@ -0,0 +1,42 @@
+package com.ku_stacks.ku_ring.edit_subscription
+
+import android.app.Activity
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.navigation3.runtime.EntryProviderScope
+import androidx.navigation3.runtime.NavKey
+import com.ku_stacks.ku_ring.compose.locals.LocalNavigator
+import com.ku_stacks.ku_ring.edit_subscription.compose.EditSubscriptionScreen
+import com.ku_stacks.ku_ring.navigation.EntryBuilderProvider
+import com.ku_stacks.ku_ring.navigation.keys.EditSubscriptionKey
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import dagger.multibindings.IntoSet
+
+class EditSubscriptionEntryBuilder : EntryBuilderProvider {
+ override fun EntryProviderScope.provide() {
+ entry {
+ val navigator = LocalNavigator.current
+ val context = LocalContext.current
+ EditSubscriptionScreen(
+ onNavigateToBack = { (context as? Activity)?.finish() },
+ onFinish = { (context as? Activity)?.finish() },
+ onAddDepartmentButtonClick = {
+ navigator.navigateToEditSubscribedDepartment(context as Activity)
+ },
+ modifier = Modifier.fillMaxSize(),
+ )
+ }
+ }
+}
+
+@Module
+@InstallIn(SingletonComponent::class)
+object EditSubscriptionEntryBuilderModule {
+ @Provides
+ @IntoSet
+ fun provideEditSubscriptionEntryBuilder(): EntryBuilderProvider = EditSubscriptionEntryBuilder()
+}
diff --git a/feature/feedback/build.gradle.kts b/feature/feedback/build.gradle.kts
index 58a614057..51bb4e087 100644
--- a/feature/feedback/build.gradle.kts
+++ b/feature/feedback/build.gradle.kts
@@ -11,6 +11,7 @@ android {
}
dependencies {
+ implementation(projects.core.navigation)
implementation(projects.core.util)
implementation(projects.core.composeUtil)
implementation(projects.core.designsystem)
diff --git a/feature/feedback/src/main/java/com/ku_stacks/ku_ring/feedback/feedback/FeedbackActivity.kt b/feature/feedback/src/main/java/com/ku_stacks/ku_ring/feedback/feedback/FeedbackActivity.kt
index 219c8369a..f4b096f41 100644
--- a/feature/feedback/src/main/java/com/ku_stacks/ku_ring/feedback/feedback/FeedbackActivity.kt
+++ b/feature/feedback/src/main/java/com/ku_stacks/ku_ring/feedback/feedback/FeedbackActivity.kt
@@ -3,72 +3,22 @@ package com.ku_stacks.ku_ring.feedback.feedback
import android.app.Activity
import android.content.Intent
import android.os.Bundle
-import androidx.activity.compose.setContent
-import androidx.activity.viewModels
-import androidx.appcompat.app.AppCompatActivity
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.ui.Modifier
-import androidx.lifecycle.flowWithLifecycle
-import androidx.lifecycle.lifecycleScope
-import com.ku_stacks.ku_ring.designsystem.kuringtheme.KuringTheme
-import com.ku_stacks.ku_ring.feedback.R
-import com.ku_stacks.ku_ring.feedback.feedback.compose.FeedbackScreen
-import com.ku_stacks.ku_ring.util.showToast
+import androidx.activity.ComponentActivity
import dagger.hilt.android.AndroidEntryPoint
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
@AndroidEntryPoint
-class FeedbackActivity : AppCompatActivity() {
-
- private val viewModel by viewModels()
-
+class FeedbackActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
-
- setupView()
- observeViewModel()
- }
-
- private fun setupView() {
- setContent {
- KuringTheme {
- FeedbackScreen(
- viewModel = viewModel,
- modifier = Modifier.fillMaxSize(),
- )
- }
- }
- }
-
- private fun observeViewModel() {
- viewModel.quit
- .flowWithLifecycle(lifecycle)
- .onEach {
- finish()
- }.launchIn(lifecycleScope)
- viewModel.toast
- .flowWithLifecycle(lifecycle)
- .onEach {
- showToast(it)
- }.launchIn(lifecycleScope)
- viewModel.toastByResource
- .flowWithLifecycle(lifecycle)
- .onEach {
- showToast(getString(it))
- }.launchIn(lifecycleScope)
- }
-
- override fun finish() {
- super.finish()
- overridePendingTransition(R.anim.anim_slide_left_enter, R.anim.anim_slide_left_exit)
+ val intent = Intent().setClassName(this, "com.ku_stacks.ku_ring.HostActivity")
+ startActivity(intent)
+ finish()
}
companion object {
fun start(activity: Activity) {
val intent = Intent(activity, FeedbackActivity::class.java)
activity.startActivity(intent)
- activity.overridePendingTransition(R.anim.anim_slide_right_enter, R.anim.anim_stay_exit)
}
}
}
diff --git a/feature/feedback/src/main/java/com/ku_stacks/ku_ring/feedback/feedback/FeedbackEntryBuilder.kt b/feature/feedback/src/main/java/com/ku_stacks/ku_ring/feedback/feedback/FeedbackEntryBuilder.kt
new file mode 100644
index 000000000..8d5f9a446
--- /dev/null
+++ b/feature/feedback/src/main/java/com/ku_stacks/ku_ring/feedback/feedback/FeedbackEntryBuilder.kt
@@ -0,0 +1,57 @@
+package com.ku_stacks.ku_ring.feedback.feedback
+
+import android.app.Activity
+import android.widget.Toast
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.hilt.navigation.compose.hiltViewModel
+import androidx.navigation3.runtime.EntryProviderScope
+import androidx.navigation3.runtime.NavKey
+import com.ku_stacks.ku_ring.feedback.feedback.compose.FeedbackScreen
+import com.ku_stacks.ku_ring.navigation.EntryBuilderProvider
+import com.ku_stacks.ku_ring.navigation.keys.FeedbackKey
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import dagger.multibindings.IntoSet
+
+class FeedbackEntryBuilder : EntryBuilderProvider {
+ override fun EntryProviderScope.provide() {
+ entry {
+ val viewModel = hiltViewModel()
+ val context = LocalContext.current
+
+ LaunchedEffect(Unit) {
+ viewModel.quit.collect {
+ (context as? Activity)?.finish()
+ }
+ }
+ LaunchedEffect(Unit) {
+ viewModel.toast.collect { message ->
+ Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
+ }
+ }
+ LaunchedEffect(Unit) {
+ viewModel.toastByResource.collect { resId ->
+ Toast.makeText(context, context.getString(resId), Toast.LENGTH_SHORT).show()
+ }
+ }
+
+ FeedbackScreen(
+ viewModel = viewModel,
+ modifier = Modifier.fillMaxSize(),
+ )
+ }
+ }
+}
+
+@Module
+@InstallIn(SingletonComponent::class)
+object FeedbackEntryBuilderModule {
+ @Provides
+ @IntoSet
+ fun provideFeedbackEntryBuilder(): EntryBuilderProvider = FeedbackEntryBuilder()
+}
diff --git a/feature/kuringbot/build.gradle.kts b/feature/kuringbot/build.gradle.kts
index b08c6bfb2..568bfa269 100644
--- a/feature/kuringbot/build.gradle.kts
+++ b/feature/kuringbot/build.gradle.kts
@@ -11,6 +11,8 @@ android {
}
dependencies {
+ implementation(projects.core.navigation)
+ implementation(projects.core.composeLocals)
implementation(projects.core.designsystem)
implementation(projects.core.preferences)
implementation(projects.core.composeUtil)
diff --git a/feature/kuringbot/src/main/java/com/ku_stacks/ku_ring/kuringbot/KuringBotActivity.kt b/feature/kuringbot/src/main/java/com/ku_stacks/ku_ring/kuringbot/KuringBotActivity.kt
index e0e863541..3489caf6a 100644
--- a/feature/kuringbot/src/main/java/com/ku_stacks/ku_ring/kuringbot/KuringBotActivity.kt
+++ b/feature/kuringbot/src/main/java/com/ku_stacks/ku_ring/kuringbot/KuringBotActivity.kt
@@ -3,37 +3,17 @@ package com.ku_stacks.ku_ring.kuringbot
import android.content.Context
import android.content.Intent
import android.os.Bundle
-import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.imePadding
-import androidx.compose.ui.Modifier
-import com.ku_stacks.ku_ring.designsystem.kuringtheme.KuringTheme
-import com.ku_stacks.ku_ring.kuringbot.compose.KuringBotScreen
-import com.ku_stacks.ku_ring.navigation.KuringNavigator
import dagger.hilt.android.AndroidEntryPoint
-import javax.inject.Inject
@AndroidEntryPoint
class KuringBotActivity : AppCompatActivity() {
- @Inject
- lateinit var navigator: KuringNavigator
-
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
-
- setContent {
- KuringTheme {
- KuringBotScreen(
- onBackButtonClick = ::finish,
- onMoveToLogin = { navigator.navigateToAuth(this) },
- modifier = Modifier
- .imePadding()
- .fillMaxSize(),
- )
- }
- }
+ val intent = Intent().setClassName(this, "com.ku_stacks.ku_ring.HostActivity")
+ startActivity(intent)
+ finish()
}
companion object {
diff --git a/feature/kuringbot/src/main/java/com/ku_stacks/ku_ring/kuringbot/KuringBotEntryBuilder.kt b/feature/kuringbot/src/main/java/com/ku_stacks/ku_ring/kuringbot/KuringBotEntryBuilder.kt
new file mode 100644
index 000000000..335498eef
--- /dev/null
+++ b/feature/kuringbot/src/main/java/com/ku_stacks/ku_ring/kuringbot/KuringBotEntryBuilder.kt
@@ -0,0 +1,42 @@
+package com.ku_stacks.ku_ring.kuringbot
+
+import android.app.Activity
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.imePadding
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.navigation3.runtime.EntryProviderScope
+import androidx.navigation3.runtime.NavKey
+import com.ku_stacks.ku_ring.compose.locals.LocalNavigator
+import com.ku_stacks.ku_ring.kuringbot.compose.KuringBotScreen
+import com.ku_stacks.ku_ring.navigation.EntryBuilderProvider
+import com.ku_stacks.ku_ring.navigation.keys.KuringBotKey
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import dagger.multibindings.IntoSet
+
+class KuringBotEntryBuilder : EntryBuilderProvider {
+ override fun EntryProviderScope.provide() {
+ entry {
+ val navigator = LocalNavigator.current
+ val context = LocalContext.current
+ KuringBotScreen(
+ onBackButtonClick = { (context as? Activity)?.finish() },
+ onMoveToLogin = { navigator.navigateToAuth(context) },
+ modifier = Modifier
+ .imePadding()
+ .fillMaxSize(),
+ )
+ }
+ }
+}
+
+@Module
+@InstallIn(SingletonComponent::class)
+object KuringBotEntryBuilderModule {
+ @Provides
+ @IntoSet
+ fun provideKuringBotEntryBuilder(): EntryBuilderProvider = KuringBotEntryBuilder()
+}
diff --git a/feature/library/build.gradle.kts b/feature/library/build.gradle.kts
index 68f379042..b803d7213 100644
--- a/feature/library/build.gradle.kts
+++ b/feature/library/build.gradle.kts
@@ -11,6 +11,7 @@ android {
dependencies {
implementation(projects.core.designsystem)
+ implementation(projects.core.navigation)
implementation(projects.core.util)
implementation(projects.data.domain)
implementation(projects.data.library)
diff --git a/feature/library/src/main/java/com/ku_stacks/ku_ring/library/LibrarySeatActivity.kt b/feature/library/src/main/java/com/ku_stacks/ku_ring/library/LibrarySeatActivity.kt
index 75ef3d660..7e9881fd6 100644
--- a/feature/library/src/main/java/com/ku_stacks/ku_ring/library/LibrarySeatActivity.kt
+++ b/feature/library/src/main/java/com/ku_stacks/ku_ring/library/LibrarySeatActivity.kt
@@ -1,117 +1,27 @@
package com.ku_stacks.ku_ring.library
import android.app.Activity
-import android.content.ActivityNotFoundException
import android.content.Intent
-import android.content.pm.PackageManager
-import android.net.Uri
-import android.os.Build
import android.os.Bundle
-import android.widget.Toast
-import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.ui.Modifier
-import com.ku_stacks.ku_ring.designsystem.kuringtheme.KuringTheme
-import com.ku_stacks.ku_ring.designsystem.R as DesignR
-import com.ku_stacks.ku_ring.library.compose.LibrarySeatScreen
import dagger.hilt.android.AndroidEntryPoint
-import timber.log.Timber
@AndroidEntryPoint
class LibrarySeatActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContent {
- KuringTheme {
- LibrarySeatScreen(
- onNavigateBack = ::finish,
- onLaunchLibraryIntent = ::launchLibrary,
- modifier = Modifier.fillMaxSize()
- )
- }
- }
- }
-
- override fun finish() {
- super.finish()
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
- overrideActivityTransition(
- OVERRIDE_TRANSITION_CLOSE,
- DesignR.anim.anim_slide_left_enter,
- DesignR.anim.anim_slide_left_exit
- )
- } else {
- overridePendingTransition(DesignR.anim.anim_slide_left_enter, DesignR.anim.anim_slide_left_exit)
- }
- }
-
- private fun launchLibrary() {
- try {
- checkKonkukLibraryInstalled()
- launchKonkukLibrary()
- } catch (e: PackageManager.NameNotFoundException) {
- launchPlayStore()
- }
- }
-
- private fun checkKonkukLibraryInstalled() {
- try {
- val packageManager = this.packageManager
- packageManager.getPackageInfo(
- KU_LIBRARY_PACKAGE_NAME,
- PackageManager.MATCH_UNINSTALLED_PACKAGES
- )
- } catch (e: PackageManager.NameNotFoundException) {
- Timber.e("PackageManager could not find $KU_LIBRARY_PACKAGE_NAME: $e")
- throw e
- }
+ val intent = Intent().setClassName(this, "com.ku_stacks.ku_ring.HostActivity")
+ startActivity(intent)
+ finish()
}
- private fun launchKonkukLibrary() {
- try {
- val intent = Intent().apply {
- setClassName(KU_LIBRARY_PACKAGE_NAME, KU_LIBRARY_CLASS_NAME)
- }
- startActivity(intent)
- } catch (e: ActivityNotFoundException) {
- Toast.makeText(this, MESSAGE_APP_NOT_FOUND, Toast.LENGTH_SHORT).show()
- }
- }
-
- private fun launchPlayStore() {
- try {
- val playStoreIntent = Intent(Intent.ACTION_VIEW).apply {
- data = Uri.parse(KU_LIBRARY_STORE_URI)
- }
- startActivity(playStoreIntent)
- } catch (e: ActivityNotFoundException) {
- Toast.makeText(this, MESSAGE_APP_NOT_FOUND, Toast.LENGTH_SHORT).show()
- }
- }
-
-
companion object {
fun start(activity: Activity) {
with(activity) {
val intent = Intent(this, LibrarySeatActivity::class.java)
startActivity(intent)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
- overrideActivityTransition(
- OVERRIDE_TRANSITION_OPEN,
- DesignR.anim.anim_slide_right_enter,
- DesignR.anim.anim_stay_exit
- )
- } else {
- overridePendingTransition(DesignR.anim.anim_slide_right_enter, DesignR.anim.anim_stay_exit)
- }
}
}
-
- private const val KU_LIBRARY_PACKAGE_NAME = "kr.ac.kku.library"
- private const val KU_LIBRARY_CLASS_NAME = "kr.ac.kku.library.MainActivity"
- private const val KU_LIBRARY_STORE_URI = "market://details?id=$KU_LIBRARY_PACKAGE_NAME"
- private const val MESSAGE_APP_NOT_FOUND = "도서관 앱을 찾을 수 없습니다."
}
}
\ No newline at end of file
diff --git a/feature/library/src/main/java/com/ku_stacks/ku_ring/library/LibrarySeatEntryBuilder.kt b/feature/library/src/main/java/com/ku_stacks/ku_ring/library/LibrarySeatEntryBuilder.kt
new file mode 100644
index 000000000..4671b1b8d
--- /dev/null
+++ b/feature/library/src/main/java/com/ku_stacks/ku_ring/library/LibrarySeatEntryBuilder.kt
@@ -0,0 +1,75 @@
+package com.ku_stacks.ku_ring.library
+
+import android.app.Activity
+import android.content.ActivityNotFoundException
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.net.Uri
+import android.widget.Toast
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.navigation3.runtime.EntryProviderScope
+import androidx.navigation3.runtime.NavKey
+import com.ku_stacks.ku_ring.library.compose.LibrarySeatScreen
+import com.ku_stacks.ku_ring.navigation.EntryBuilderProvider
+import com.ku_stacks.ku_ring.navigation.keys.LibrarySeatKey
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import dagger.multibindings.IntoSet
+import timber.log.Timber
+
+class LibrarySeatEntryBuilder : EntryBuilderProvider {
+ override fun EntryProviderScope.provide() {
+ entry {
+ val context = LocalContext.current
+ LibrarySeatScreen(
+ onNavigateBack = { (context as? Activity)?.finish() },
+ onLaunchLibraryIntent = {
+ try {
+ context.packageManager.getPackageInfo(
+ KU_LIBRARY_PACKAGE_NAME,
+ PackageManager.MATCH_UNINSTALLED_PACKAGES
+ )
+ try {
+ val intent = Intent().apply {
+ setClassName(KU_LIBRARY_PACKAGE_NAME, KU_LIBRARY_CLASS_NAME)
+ }
+ context.startActivity(intent)
+ } catch (e: ActivityNotFoundException) {
+ Toast.makeText(context, MESSAGE_APP_NOT_FOUND, Toast.LENGTH_SHORT).show()
+ }
+ } catch (e: PackageManager.NameNotFoundException) {
+ Timber.e("PackageManager could not find $KU_LIBRARY_PACKAGE_NAME: $e")
+ try {
+ val playStoreIntent = Intent(Intent.ACTION_VIEW).apply {
+ data = Uri.parse(KU_LIBRARY_STORE_URI)
+ }
+ context.startActivity(playStoreIntent)
+ } catch (e: ActivityNotFoundException) {
+ Toast.makeText(context, MESSAGE_APP_NOT_FOUND, Toast.LENGTH_SHORT).show()
+ }
+ }
+ },
+ modifier = Modifier.fillMaxSize(),
+ )
+ }
+ }
+
+ private companion object {
+ const val KU_LIBRARY_PACKAGE_NAME = "kr.ac.kku.library"
+ const val KU_LIBRARY_CLASS_NAME = "kr.ac.kku.library.MainActivity"
+ const val KU_LIBRARY_STORE_URI = "market://details?id=$KU_LIBRARY_PACKAGE_NAME"
+ const val MESSAGE_APP_NOT_FOUND = "도서관 앱을 찾을 수 없습니다."
+ }
+}
+
+@Module
+@InstallIn(SingletonComponent::class)
+object LibrarySeatEntryBuilderModule {
+ @Provides
+ @IntoSet
+ fun provideLibrarySeatEntryBuilder(): EntryBuilderProvider = LibrarySeatEntryBuilder()
+}
diff --git a/feature/notice_detail/build.gradle.kts b/feature/notice_detail/build.gradle.kts
index a4db11517..17d6a19bb 100644
--- a/feature/notice_detail/build.gradle.kts
+++ b/feature/notice_detail/build.gradle.kts
@@ -21,6 +21,7 @@ dependencies {
implementation(projects.domain.noticecomment)
implementation(projects.domain.report)
implementation(projects.domain.navigation)
+ implementation(projects.core.navigation)
implementation(libs.bundles.compose.interop)
}
diff --git a/feature/notice_detail/src/main/java/com/ku_stacks/ku_ring/notice_detail/NoticeWebActivity.kt b/feature/notice_detail/src/main/java/com/ku_stacks/ku_ring/notice_detail/NoticeWebActivity.kt
index 1a06982f3..ed2ee096f 100644
--- a/feature/notice_detail/src/main/java/com/ku_stacks/ku_ring/notice_detail/NoticeWebActivity.kt
+++ b/feature/notice_detail/src/main/java/com/ku_stacks/ku_ring/notice_detail/NoticeWebActivity.kt
@@ -4,14 +4,8 @@ import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
-import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.ui.Modifier
-import androidx.navigation.compose.rememberNavController
-import com.ku_stacks.ku_ring.designsystem.kuringtheme.KuringTheme
import com.ku_stacks.ku_ring.domain.WebViewNotice
-import com.ku_stacks.ku_ring.compose.locals.KuringCompositionLocalProvider
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
@@ -19,29 +13,10 @@ class NoticeWebActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
-
- // Deprecated되지 않은 다른 함수가 API 33 이상에서만 사용할 수 있어서 부득이하게 deprecated 함수를 사용
- val webViewNotice = intent.getSerializableExtra(WebViewNotice.EXTRA_KEY) as? WebViewNotice
- ?: throw IllegalStateException("WebViewNotice should not be null.")
-
- setContent {
- KuringCompositionLocalProvider {
- KuringTheme {
- val navController = rememberNavController()
- NoticeDetailScreen(
- navController = navController,
- webViewNotice = webViewNotice,
- onClose = ::finish,
- modifier = Modifier.fillMaxSize(),
- )
- }
- }
- }
- }
-
- override fun finish() {
- super.finish()
- overridePendingTransition(R.anim.anim_slide_left_enter, R.anim.anim_slide_left_exit)
+ val redirectIntent = Intent().setClassName(this, "com.ku_stacks.ku_ring.HostActivity")
+ intent.extras?.let { redirectIntent.putExtras(it) }
+ startActivity(redirectIntent)
+ finish()
}
companion object {
diff --git a/feature/notice_detail/src/main/java/com/ku_stacks/ku_ring/notice_detail/NoticeWebEntryBuilder.kt b/feature/notice_detail/src/main/java/com/ku_stacks/ku_ring/notice_detail/NoticeWebEntryBuilder.kt
new file mode 100644
index 000000000..935309afe
--- /dev/null
+++ b/feature/notice_detail/src/main/java/com/ku_stacks/ku_ring/notice_detail/NoticeWebEntryBuilder.kt
@@ -0,0 +1,47 @@
+package com.ku_stacks.ku_ring.notice_detail
+
+import android.app.Activity
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.navigation.compose.rememberNavController
+import androidx.navigation3.runtime.EntryProviderScope
+import androidx.navigation3.runtime.NavKey
+import com.ku_stacks.ku_ring.domain.WebViewNotice
+import com.ku_stacks.ku_ring.navigation.EntryBuilderProvider
+import com.ku_stacks.ku_ring.navigation.keys.NoticeWebKey
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import dagger.multibindings.IntoSet
+
+class NoticeWebEntryBuilder : EntryBuilderProvider {
+ override fun EntryProviderScope.provide() {
+ entry { key ->
+ val context = LocalContext.current
+ val webViewNotice = WebViewNotice(
+ url = key.url,
+ articleId = key.articleId,
+ id = key.id.toIntOrNull() ?: 0,
+ category = key.category,
+ subject = key.subject,
+ )
+ val navController = rememberNavController()
+ NoticeDetailScreen(
+ navController = navController,
+ webViewNotice = webViewNotice,
+ onClose = { (context as? Activity)?.finish() },
+ modifier = Modifier.fillMaxSize(),
+ )
+ }
+ }
+}
+
+@Module
+@InstallIn(SingletonComponent::class)
+object NoticeWebEntryBuilderModule {
+ @Provides
+ @IntoSet
+ fun provideNoticeWebEntryBuilder(): EntryBuilderProvider = NoticeWebEntryBuilder()
+}
diff --git a/feature/notification/build.gradle.kts b/feature/notification/build.gradle.kts
index 12def65e8..b5c70c7f1 100644
--- a/feature/notification/build.gradle.kts
+++ b/feature/notification/build.gradle.kts
@@ -12,6 +12,8 @@ android {
}
dependencies {
+ implementation(projects.core.navigation)
+ implementation(projects.core.composeLocals)
implementation(projects.core.designsystem)
implementation(projects.core.preferences)
implementation(projects.core.ui)
diff --git a/feature/notification/src/main/java/com/ku_stacks/ku_ring/notification/NotificationActivity.kt b/feature/notification/src/main/java/com/ku_stacks/ku_ring/notification/NotificationActivity.kt
index 5d2225999..c59a54875 100644
--- a/feature/notification/src/main/java/com/ku_stacks/ku_ring/notification/NotificationActivity.kt
+++ b/feature/notification/src/main/java/com/ku_stacks/ku_ring/notification/NotificationActivity.kt
@@ -4,40 +4,16 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
-import androidx.activity.compose.setContent
-import androidx.activity.enableEdgeToEdge
-import com.ku_stacks.ku_ring.designsystem.kuringtheme.KuringTheme
-import com.ku_stacks.ku_ring.domain.Notification
-import com.ku_stacks.ku_ring.navigation.KuringNavigator
-import com.ku_stacks.ku_ring.notification.compose.innerscreen.NotificationScreen
import dagger.hilt.android.AndroidEntryPoint
-import javax.inject.Inject
@AndroidEntryPoint
class NotificationActivity : ComponentActivity() {
- @Inject
- lateinit var navigator: KuringNavigator
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- enableEdgeToEdge()
- setContent {
- KuringTheme {
- NotificationScreen(
- onNavigateUp = ::finish,
- onNavigateToEditSubscription = ::navigateToEditSubscription,
- onNotificationClick = ::determineNavigationTarget
- )
- }
- }
- }
-
- private fun navigateToEditSubscription() {
- navigator.navigateToEditSubscription(this)
- }
-
- private fun determineNavigationTarget(notification: Notification) {
- // TODO: 이동 화면 추가
+ val intent = Intent().setClassName(this, "com.ku_stacks.ku_ring.HostActivity")
+ startActivity(intent)
+ finish()
}
companion object {
diff --git a/feature/notification/src/main/java/com/ku_stacks/ku_ring/notification/NotificationEntryBuilder.kt b/feature/notification/src/main/java/com/ku_stacks/ku_ring/notification/NotificationEntryBuilder.kt
new file mode 100644
index 000000000..50591071f
--- /dev/null
+++ b/feature/notification/src/main/java/com/ku_stacks/ku_ring/notification/NotificationEntryBuilder.kt
@@ -0,0 +1,37 @@
+package com.ku_stacks.ku_ring.notification
+
+import android.app.Activity
+import androidx.compose.ui.platform.LocalContext
+import androidx.navigation3.runtime.EntryProviderScope
+import androidx.navigation3.runtime.NavKey
+import com.ku_stacks.ku_ring.compose.locals.LocalNavigator
+import com.ku_stacks.ku_ring.navigation.EntryBuilderProvider
+import com.ku_stacks.ku_ring.navigation.keys.NotificationKey
+import com.ku_stacks.ku_ring.notification.compose.innerscreen.NotificationScreen
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import dagger.multibindings.IntoSet
+
+class NotificationEntryBuilder : EntryBuilderProvider {
+ override fun EntryProviderScope.provide() {
+ entry {
+ val navigator = LocalNavigator.current
+ val context = LocalContext.current
+ NotificationScreen(
+ onNavigateUp = { (context as? Activity)?.finish() },
+ onNavigateToEditSubscription = { navigator.navigateToEditSubscription(context as Activity) },
+ onNotificationClick = {},
+ )
+ }
+ }
+}
+
+@Module
+@InstallIn(SingletonComponent::class)
+object NotificationEntryBuilderModule {
+ @Provides
+ @IntoSet
+ fun provideNotificationEntryBuilder(): EntryBuilderProvider = NotificationEntryBuilder()
+}
diff --git a/feature/notion/build.gradle.kts b/feature/notion/build.gradle.kts
index 35f029bbf..b071123a4 100644
--- a/feature/notion/build.gradle.kts
+++ b/feature/notion/build.gradle.kts
@@ -10,6 +10,7 @@ android {
}
dependencies {
+ implementation(projects.core.navigation)
implementation(projects.core.util)
implementation(projects.core.designsystem)
}
diff --git a/feature/notion/src/main/java/com/ku_stacks/ku_ring/notion/NotionViewActivity.kt b/feature/notion/src/main/java/com/ku_stacks/ku_ring/notion/NotionViewActivity.kt
index 6cd7f19e3..94e08aac9 100644
--- a/feature/notion/src/main/java/com/ku_stacks/ku_ring/notion/NotionViewActivity.kt
+++ b/feature/notion/src/main/java/com/ku_stacks/ku_ring/notion/NotionViewActivity.kt
@@ -1,41 +1,19 @@
package com.ku_stacks.ku_ring.notion
-import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.os.Bundle
-import androidx.activity.compose.setContent
-import androidx.appcompat.app.AppCompatActivity
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.ui.Modifier
-import com.ku_stacks.ku_ring.designsystem.kuringtheme.KuringTheme
-import com.ku_stacks.ku_ring.util.TransitionType
-import com.ku_stacks.ku_ring.util.setActivityTransition
+import androidx.activity.ComponentActivity
+import dagger.hilt.android.AndroidEntryPoint
-class NotionViewActivity : AppCompatActivity() {
+@AndroidEntryPoint
+class NotionViewActivity : ComponentActivity() {
- @SuppressLint("SetJavaScriptEnabled")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
-
- val url = intent.getStringExtra(NOTION_URL)
- setContent {
- KuringTheme {
- NotionScreen(
- url = url,
- modifier = Modifier.fillMaxSize(),
- )
- }
- }
- }
-
- override fun finish() {
- super.finish()
- setActivityTransition(
- TransitionType.CLOSE,
- R.anim.anim_slide_left_enter,
- R.anim.anim_slide_left_exit
- )
+ val intent = Intent().setClassName(this, "com.ku_stacks.ku_ring.HostActivity")
+ startActivity(intent)
+ finish()
}
companion object {
diff --git a/feature/notion/src/main/java/com/ku_stacks/ku_ring/notion/NotionViewEntryBuilder.kt b/feature/notion/src/main/java/com/ku_stacks/ku_ring/notion/NotionViewEntryBuilder.kt
new file mode 100644
index 000000000..767633476
--- /dev/null
+++ b/feature/notion/src/main/java/com/ku_stacks/ku_ring/notion/NotionViewEntryBuilder.kt
@@ -0,0 +1,32 @@
+package com.ku_stacks.ku_ring.notion
+
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.ui.Modifier
+import androidx.navigation3.runtime.EntryProviderScope
+import androidx.navigation3.runtime.NavKey
+import com.ku_stacks.ku_ring.navigation.EntryBuilderProvider
+import com.ku_stacks.ku_ring.navigation.keys.NotionViewKey
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import dagger.multibindings.IntoSet
+
+class NotionViewEntryBuilder : EntryBuilderProvider {
+ override fun EntryProviderScope.provide() {
+ entry { key ->
+ NotionScreen(
+ url = key.url,
+ modifier = Modifier.fillMaxSize(),
+ )
+ }
+ }
+}
+
+@Module
+@InstallIn(SingletonComponent::class)
+object NotionViewEntryBuilderModule {
+ @Provides
+ @IntoSet
+ fun provideNotionViewEntryBuilder(): EntryBuilderProvider = NotionViewEntryBuilder()
+}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 6e39a5bd6..172e9c247 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -64,6 +64,7 @@ javax-inject = "1"
naver-map = "1.9.0"
play-service-location = "21.3.0"
naver-map-location = "21.0.2"
+navigation3 = "1.0.1"
[libraries]
# Project-level dependencies
@@ -206,6 +207,7 @@ ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx
# Other libraries
keyboardvisibilityevent = 'net.yslibrary.keyboardvisibilityevent:keyboardvisibilityevent:3.0.0-RC3'
leakcanary-android = 'com.squareup.leakcanary:leakcanary-android:2.14'
+lifecycle-viewmodel-navigation3 = { module = "androidx.lifecycle:lifecycle-viewmodel-navigation3", version = "2.11.0-alpha03" }
pageindicatorview = 'com.romandanylyk:pageindicatorview:1.0.3'
shimmer = 'com.facebook.shimmer:shimmer:0.5.0'
timber = 'com.jakewharton.timber:timber:5.0.1'
@@ -213,6 +215,8 @@ semver = "net.swiftzer.semver:semver:2.1.0"
naver-map = { module = "io.github.fornewid:naver-map-compose", version.ref = "naver-map" }
play-service-location = { module = "com.google.android.gms:play-services-location", version.ref = "play-service-location" }
naver-map-location = { module = "io.github.fornewid:naver-map-location", version.ref = "naver-map-location" }
+navigation3-runtime = { module = "androidx.navigation3:navigation3-runtime", version.ref = "navigation3" }
+navigation3-ui = { module = "androidx.navigation3:navigation3-ui", version.ref = "navigation3" }
[bundles]
retrofit = [
diff --git a/settings.gradle.kts b/settings.gradle.kts
index d536b106e..3f514735f 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -36,6 +36,7 @@ include(
":core:firebase-crashlytics",
":core:firebase-messaging",
":core:compose-locals",
+ ":core:navigation",
// data modules
":data:domain",
":data:domain:testUtils",