diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index fcab7b1..e928a13 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -18,14 +18,20 @@
android:screenOrientation="portrait"
android:name=".MainActivity"
android:exported="true"
- android:label="@string/app_name"
android:windowSoftInputMode="adjustResize"
- android:theme="@style/Theme.Pokit">
+ android:theme="@style/Theme.Pokit"
+ android:launchMode="singleInstance"
+ tools:ignore="DiscouragedApi,LockedOrientationActivity">
+
+
+
+
+
diff --git a/app/src/main/java/pokitmons/pokit/MainActivity.kt b/app/src/main/java/pokitmons/pokit/MainActivity.kt
index 3c78fe9..7fd8ede 100644
--- a/app/src/main/java/pokitmons/pokit/MainActivity.kt
+++ b/app/src/main/java/pokitmons/pokit/MainActivity.kt
@@ -2,10 +2,12 @@ package pokitmons.pokit
import android.content.ClipData
import android.content.ClipboardManager
+import android.content.Intent
import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
+import androidx.activity.viewModels
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
@@ -24,14 +26,18 @@ import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.delay
+import pokitmons.pokit.core.feature.flow.collectAsEffect
import pokitmons.pokit.core.ui.theme.PokitTheme
-import pokitmons.pokit.home.model.ClipboardLinkManager
+import pokitmons.pokit.navigation.AddLink
import pokitmons.pokit.navigation.RootNavHost
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
+ private val viewModel: MainViewModel by viewModels()
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ handleSharedLinkIntent(intent)
setContent {
var showSplash by remember { mutableStateOf(true) }
@@ -44,6 +50,12 @@ class MainActivity : ComponentActivity() {
val navBackStackEntry by navHostController.currentBackStackEntryAsState()
val currentDestination by remember(navBackStackEntry) { derivedStateOf { navBackStackEntry?.destination } }
+ viewModel.navigationEvent.collectAsEffect { navigationEvent ->
+ if (navigationEvent is NavigationEvent.AddLink) {
+ navHostController.navigate("${AddLink.route}?${AddLink.linkUrl}=${navigationEvent.url}")
+ }
+ }
+
PokitTheme {
if (showSplash) {
SplashScreen()
@@ -53,25 +65,26 @@ class MainActivity : ComponentActivity() {
LaunchedEffect(currentDestination) {
currentDestination?.route?.let { route ->
- // 믹스패널/파베 애널리틱스 화면 이동 로깅용
+ viewModel.setCurrentRoute(route)
}
}
}
}
}
+ override fun onNewIntent(intent: Intent) {
+ super.onNewIntent(intent)
+ handleSharedLinkIntent(intent)
+ }
+
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (hasFocus) {
val clipboardManager = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
clipboardManager.primaryClip?.let { clipData ->
- if (clipData.itemCount == 0) return@let
- val clipboardTextData = clipData.getItemAt(0).text.toString()
-
- if (!ClipboardLinkManager.checkUrlIsValid(clipboardTextData)) return@let
-
- ClipboardLinkManager.setClipboardLink(clipboardTextData)
+ val setClipDataSuccess = viewModel.setClipData(clipData)
+ if (!setClipDataSuccess) return@let
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
clipboardManager.clearPrimaryClip()
} else {
@@ -81,6 +94,17 @@ class MainActivity : ComponentActivity() {
}
}
}
+
+ private fun handleSharedLinkIntent(intent: Intent) {
+ val action = intent.action ?: return
+
+ val isSharedLinkData = (action == Intent.ACTION_SEND && intent.type == "text/plain")
+ if (isSharedLinkData) {
+ intent.getStringExtra(Intent.EXTRA_TEXT)?.let { url ->
+ viewModel.setSharedLinkUrl(url)
+ }
+ }
+ }
}
@Composable
diff --git a/app/src/main/java/pokitmons/pokit/MainViewModel.kt b/app/src/main/java/pokitmons/pokit/MainViewModel.kt
new file mode 100644
index 0000000..75711b8
--- /dev/null
+++ b/app/src/main/java/pokitmons/pokit/MainViewModel.kt
@@ -0,0 +1,56 @@
+package pokitmons.pokit
+
+import android.content.ClipData
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.update
+import kotlinx.coroutines.launch
+import pokitmons.pokit.core.feature.flow.EventFlow
+import pokitmons.pokit.core.feature.flow.MutableEventFlow
+import pokitmons.pokit.core.feature.flow.asEventFlow
+import pokitmons.pokit.home.model.ClipboardLinkManager
+import pokitmons.pokit.home.model.PendingSharedLinkManager
+import pokitmons.pokit.navigation.Login
+import pokitmons.pokit.navigation.ROUTE_WITHOUT_LOGIN
+import javax.inject.Inject
+
+@HiltViewModel
+class MainViewModel @Inject constructor() : ViewModel() {
+ private val _currentRoute: MutableStateFlow = MutableStateFlow(Login.route)
+ val currentRoute: StateFlow = _currentRoute.asStateFlow()
+
+ private val _navigationEvent: MutableEventFlow = MutableEventFlow()
+ val navigationEvent: EventFlow = _navigationEvent.asEventFlow()
+
+ fun setCurrentRoute(route: String) {
+ _currentRoute.update { route }
+ }
+
+ fun setClipData(clipData: ClipData): Boolean {
+ if (clipData.itemCount == 0) return false
+ val clipboardTextData = clipData.getItemAt(0).text.toString()
+
+ if (!ClipboardLinkManager.checkUrlIsValid(clipboardTextData)) return false
+
+ ClipboardLinkManager.setClipboardLink(clipboardTextData)
+ return true
+ }
+
+ fun setSharedLinkUrl(url: String) {
+ if (currentRoute.value in ROUTE_WITHOUT_LOGIN) {
+ PendingSharedLinkManager.setSharedLink(url)
+ } else {
+ viewModelScope.launch {
+ _navigationEvent.emit(NavigationEvent.AddLink(url))
+ }
+ }
+ }
+}
+
+sealed class NavigationEvent {
+ data class AddLink(val url: String) : NavigationEvent()
+}
diff --git a/app/src/main/java/pokitmons/pokit/navigation/RootDestination.kt b/app/src/main/java/pokitmons/pokit/navigation/RootDestination.kt
index f2b1a43..d221470 100644
--- a/app/src/main/java/pokitmons/pokit/navigation/RootDestination.kt
+++ b/app/src/main/java/pokitmons/pokit/navigation/RootDestination.kt
@@ -3,6 +3,8 @@ package pokitmons.pokit.navigation
import androidx.navigation.NavType
import androidx.navigation.navArgument
+val ROUTE_WITHOUT_LOGIN = listOf(Login.route, TermOfService.route, InputNickname.route, SelectKeyword.route, SignUpSuccess.route)
+
object Login {
val route: String = "login"
}
diff --git a/app/src/main/java/pokitmons/pokit/navigation/RootNavHost.kt b/app/src/main/java/pokitmons/pokit/navigation/RootNavHost.kt
index 3ea5bfe..439d88d 100644
--- a/app/src/main/java/pokitmons/pokit/navigation/RootNavHost.kt
+++ b/app/src/main/java/pokitmons/pokit/navigation/RootNavHost.kt
@@ -154,7 +154,7 @@ fun RootNavHost(
onNavigateToEditNickname = { navHostController.navigate(EditNickname.route) },
onNavigateToLogin = {
navHostController.navigate(Login.route) {
- popUpTo(navHostController.graph.startDestinationId) {
+ popUpTo(navHostController.graph.id) {
inclusive = true
}
}
diff --git a/feature/home/src/main/java/pokitmons/pokit/home/HomeScreen.kt b/feature/home/src/main/java/pokitmons/pokit/home/HomeScreen.kt
index bfa97b1..a48fea1 100644
--- a/feature/home/src/main/java/pokitmons/pokit/home/HomeScreen.kt
+++ b/feature/home/src/main/java/pokitmons/pokit/home/HomeScreen.kt
@@ -70,6 +70,9 @@ fun HomeScreen(
HomeSideEffect.NavigateToAddPokit -> {
onNavigateAddPokit()
}
+ is HomeSideEffect.NavigateToAddLink -> {
+ onNavigateAddLink(homeSideEffect.url)
+ }
}
}
diff --git a/feature/home/src/main/java/pokitmons/pokit/home/model/HomeSideEffect.kt b/feature/home/src/main/java/pokitmons/pokit/home/model/HomeSideEffect.kt
index 3b0f634..d44c77e 100644
--- a/feature/home/src/main/java/pokitmons/pokit/home/model/HomeSideEffect.kt
+++ b/feature/home/src/main/java/pokitmons/pokit/home/model/HomeSideEffect.kt
@@ -2,4 +2,5 @@ package pokitmons.pokit.home.model
sealed class HomeSideEffect {
data object NavigateToAddPokit : HomeSideEffect()
+ data class NavigateToAddLink(val url: String) : HomeSideEffect()
}
diff --git a/feature/home/src/main/java/pokitmons/pokit/home/model/PendingSharedLinkManager.kt b/feature/home/src/main/java/pokitmons/pokit/home/model/PendingSharedLinkManager.kt
new file mode 100644
index 0000000..068c488
--- /dev/null
+++ b/feature/home/src/main/java/pokitmons/pokit/home/model/PendingSharedLinkManager.kt
@@ -0,0 +1,19 @@
+package pokitmons.pokit.home.model
+
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import pokitmons.pokit.core.feature.flow.EventFlow
+import pokitmons.pokit.core.feature.flow.MutableEventFlow
+import pokitmons.pokit.core.feature.flow.asEventFlow
+
+object PendingSharedLinkManager {
+ private val _sharedLinkUrl: MutableEventFlow = MutableEventFlow()
+ val sharedLinkUrl: EventFlow = _sharedLinkUrl.asEventFlow()
+
+ fun setSharedLink(linkUrl: String) {
+ CoroutineScope(Dispatchers.IO).launch {
+ _sharedLinkUrl.emit(linkUrl)
+ }
+ }
+}
diff --git a/feature/home/src/main/java/pokitmons/pokit/home/pokit/PokitViewModel.kt b/feature/home/src/main/java/pokitmons/pokit/home/pokit/PokitViewModel.kt
index 4da93d5..10de119 100644
--- a/feature/home/src/main/java/pokitmons/pokit/home/pokit/PokitViewModel.kt
+++ b/feature/home/src/main/java/pokitmons/pokit/home/pokit/PokitViewModel.kt
@@ -34,6 +34,7 @@ import pokitmons.pokit.home.model.ClipboardLinkManager
import pokitmons.pokit.home.model.HomeSideEffect
import pokitmons.pokit.home.model.HomeToastMessage
import pokitmons.pokit.home.model.LinkAddToastMessage
+import pokitmons.pokit.home.model.PendingSharedLinkManager
import javax.inject.Inject
import kotlin.math.max
import com.strayalpaca.pokitdetail.model.Link as DetailLink
@@ -107,6 +108,14 @@ class PokitViewModel @Inject constructor(
}
}
+ private fun initPendingSharedLinkUrlDetector() {
+ viewModelScope.launch {
+ PendingSharedLinkManager.sharedLinkUrl.collectLatest { linkUrl ->
+ _sideEffect.emit(HomeSideEffect.NavigateToAddLink(linkUrl))
+ }
+ }
+ }
+
private fun initPokitUpdateEventDetector() {
viewModelScope.launch {
PokitUpdateEvent.updatedPokit.collectLatest { updatedPokit ->
@@ -239,6 +248,7 @@ class PokitViewModel @Inject constructor(
initPokitAddEventDetector()
initLinkRemoveEventDetector()
initClipboardLinkUrlDetector()
+ initPendingSharedLinkUrlDetector()
loadUnCategoryLinks()
loadPokits()