diff --git a/core/designsystem/src/main/java/com/terning/core/designsystem/type/NotificationRedirect.kt b/core/designsystem/src/main/java/com/terning/core/designsystem/type/NotificationRedirect.kt new file mode 100644 index 000000000..9b85a3d8b --- /dev/null +++ b/core/designsystem/src/main/java/com/terning/core/designsystem/type/NotificationRedirect.kt @@ -0,0 +1,12 @@ +package com.terning.core.designsystem.type + +enum class NotificationRedirect(val path: String) { + CALENDAR("calendar"), + HOME("home"), + SEARCH("search"); + + companion object { + fun from(type: String?): NotificationRedirect? = + entries.firstOrNull { it.path.equals(type, ignoreCase = true) } + } +} diff --git a/core/designsystem/src/main/java/com/terning/core/designsystem/util/DeeplinkDefaults.kt b/core/designsystem/src/main/java/com/terning/core/designsystem/util/DeeplinkDefaults.kt new file mode 100644 index 000000000..211113ff9 --- /dev/null +++ b/core/designsystem/src/main/java/com/terning/core/designsystem/util/DeeplinkDefaults.kt @@ -0,0 +1,7 @@ +package com.terning.core.designsystem.util + +object DeeplinkDefaults { + const val REDIRECT: String = "redirect" + + fun build(base: String) = "terning://${base}" +} \ No newline at end of file diff --git a/core/firebase/build.gradle.kts b/core/firebase/build.gradle.kts index 60eaa8ce1..ffbed7ebc 100644 --- a/core/firebase/build.gradle.kts +++ b/core/firebase/build.gradle.kts @@ -11,6 +11,7 @@ android { dependencies { //core implementation(projects.core.navigator) + implementation(projects.core.designsystem) // domain implementation(projects.domain.user) @@ -23,4 +24,7 @@ dependencies { implementation(libs.firebase.analytics) implementation(libs.firebase.messaging) implementation(libs.firebase.config) + + // coil + implementation(libs.coil.compose) } \ No newline at end of file diff --git a/core/firebase/src/main/java/com/terning/core/firebase/messageservice/TerningMessagingService.kt b/core/firebase/src/main/java/com/terning/core/firebase/messageservice/TerningMessagingService.kt index 158ac44a7..aa680ddd2 100644 --- a/core/firebase/src/main/java/com/terning/core/firebase/messageservice/TerningMessagingService.kt +++ b/core/firebase/src/main/java/com/terning/core/firebase/messageservice/TerningMessagingService.kt @@ -1,15 +1,22 @@ package com.terning.core.firebase.messageservice +import android.app.ActivityManager import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent +import android.content.Context import android.content.Intent import androidx.core.app.NotificationCompat -import androidx.core.app.NotificationManagerCompat import androidx.core.content.getSystemService import androidx.core.net.toUri +import coil3.BitmapImage +import coil3.ImageLoader +import coil3.request.ImageRequest import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage +import com.terning.core.designsystem.type.NotificationRedirect +import com.terning.core.designsystem.util.DeeplinkDefaults +import com.terning.core.designsystem.util.DeeplinkDefaults.REDIRECT import com.terning.core.firebase.R import com.terning.domain.user.repository.UserRepository import com.terning.navigator.NavigatorProvider @@ -36,44 +43,53 @@ class TerningMessagingService : FirebaseMessagingService() { override fun handleIntent(intent: Intent?) { super.handleIntent(intent) - if (intent?.getStringExtra(TITLE)?.isEmpty() == true - || !userRepository.getAlarmAvailable() - ) return - - val title = intent?.getStringExtra(TITLE).orEmpty() - val body = intent?.getStringExtra(BODY).orEmpty() - val type = intent?.getStringExtra(TYPE).orEmpty() - - sendNotification( - title = title, - body = body, - type = type + extractInformation( + title = intent?.getStringExtra(TITLE), + body = intent?.getStringExtra(BODY), + type = intent?.getStringExtra(TYPE), + imageUrl = intent?.getStringExtra(IMAGE_URL) ) } override fun onMessageReceived(message: RemoteMessage) { super.onMessageReceived(message) - if (message.data.isEmpty() - || !userRepository.getAlarmAvailable() - ) return + extractInformation( + title = message.data[TITLE], + body = message.data[BODY], + type = message.data[TYPE], + imageUrl = message.data[IMAGE_URL] + ) + } - val title = message.data[TITLE].orEmpty() - val body = message.data[BODY].orEmpty() - val type = message.data[TYPE].orEmpty() + private fun extractInformation( + title: String?, + body: String?, + type: String?, + imageUrl: String? + ) { + if (title.isNullOrEmpty() || !userRepository.getAlarmAvailable()) return sendNotification( title = title, - body = body, - type = type + body = body.orEmpty(), + type = type.orEmpty(), + imageUrl = imageUrl.orEmpty() ) } - private fun sendNotification(title: String, body: String, type: String) { + private fun sendNotification( + title: String, + body: String, + type: String, + imageUrl: String + ) { val notifyId = Random().nextInt() - val intent = navigatorProvider.getMainActivityIntent(deeplink = type).apply { + val isForeground = isAppInForeground() + val deeplink = buildDeeplink(type, isForeground) + val intent = navigatorProvider.getMainActivityIntent(deeplink = deeplink).apply { action = Intent.ACTION_VIEW - data = type.toUri() + data = deeplink.toUri() flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP } val pendingIntent = PendingIntent.getActivity( @@ -82,26 +98,59 @@ class TerningMessagingService : FirebaseMessagingService() { intent, PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_MUTABLE ) - val channelId: String = CHANNEL_ID val notificationBuilder = - NotificationCompat.Builder(this, channelId).apply { + NotificationCompat.Builder(this, CHANNEL_ID).apply { setSmallIcon(R.mipmap.ic_terning_launcher) setContentTitle(title) setContentText(body) - setPriority(NotificationManagerCompat.IMPORTANCE_HIGH) + setAutoCancel(true) + setPriority(NotificationCompat.PRIORITY_HIGH) setContentIntent(pendingIntent) } - - getSystemService()?.run { - createNotificationChannel( - NotificationChannel( - channelId, - channelId, - NotificationManager.IMPORTANCE_HIGH, - ), + val notificationManager = getSystemService() + notificationManager?.createNotificationChannel( + NotificationChannel( + CHANNEL_ID, + CHANNEL_ID, + NotificationManager.IMPORTANCE_HIGH ) - notify(notifyId, notificationBuilder.build()) - } + ) + val imageLoader = ImageLoader(this) + val request = ImageRequest.Builder(this) + .data(imageUrl) + .target( + onSuccess = { image -> + val bitmap = (image as BitmapImage).bitmap + notificationBuilder.setLargeIcon(bitmap) + notificationManager?.notify(notifyId, notificationBuilder.build()) + }, + onError = { + notificationManager?.notify(notifyId, notificationBuilder.build()) + } + ) + .build() + + imageLoader.enqueue(request) + } + + private fun isAppInForeground(): Boolean { + val appProcesses = + (getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager).runningAppProcesses + + return appProcesses?.any { + val isForeground = + it.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND + val isCurrentApp = it.processName == packageName + + isForeground && isCurrentApp + } == true + } + + private fun buildDeeplink(type: String, isForeground: Boolean): String { + val base = NotificationRedirect.from(type) ?: return "" + + return if (isForeground) DeeplinkDefaults.build(base.path) + else DeeplinkDefaults.build("splash?$REDIRECT=${base.path}") } companion object { @@ -109,5 +158,6 @@ class TerningMessagingService : FirebaseMessagingService() { private const val TITLE: String = "title" private const val BODY: String = "body" private const val TYPE: String = "type" + private const val IMAGE_URL: String = "imageUrl" } -} \ No newline at end of file +} diff --git a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/CalendarRoute.kt b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/CalendarRoute.kt index 8a050444e..40babcd3f 100644 --- a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/CalendarRoute.kt +++ b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/CalendarRoute.kt @@ -48,7 +48,6 @@ fun CalendarRoute( val uiState by viewModel.uiState.collectAsStateWithLifecycle() val amplitudeTracker = LocalTracker.current - CalendarScreen( uiState = uiState, navigateToAnnouncement = navigateToAnnouncement, diff --git a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/navigation/CalendarNavigation.kt b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/navigation/CalendarNavigation.kt index 2590ac671..7c4c10aad 100644 --- a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/navigation/CalendarNavigation.kt +++ b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/navigation/CalendarNavigation.kt @@ -7,11 +7,12 @@ import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable +import androidx.navigation.navDeepLink +import com.terning.core.designsystem.util.DeeplinkDefaults import com.terning.core.navigation.MainTabRoute import com.terning.feature.calendar.calendar.CalendarRoute import kotlinx.serialization.Serializable - fun NavController.navigateCalendar(navOptions: NavOptions? = null) { navigate( route = Calendar, @@ -23,7 +24,13 @@ fun NavGraphBuilder.calendarNavGraph( navigateIntern: (Long) -> Unit, paddingValues: PaddingValues ) { - composable { + composable( + deepLinks = listOf( + navDeepLink( + basePath = DeeplinkDefaults.build("calendar") + ) + ) + ) { CalendarRoute( modifier = Modifier.padding(paddingValues), navigateToAnnouncement = navigateIntern diff --git a/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt b/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt index f6264aac8..e1a3c0fb5 100644 --- a/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt +++ b/feature/home/src/main/java/com/terning/feature/home/HomeRoute.kt @@ -19,7 +19,6 @@ import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -41,7 +40,6 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.PermissionStatus import com.google.accompanist.permissions.isGranted import com.google.accompanist.permissions.rememberPermissionState -import com.google.accompanist.systemuicontroller.rememberSystemUiController import com.terning.core.analytics.EventType import com.terning.core.analytics.LocalTracker import com.terning.core.designsystem.R.raw.paging_loading_animation @@ -105,21 +103,6 @@ fun HomeRoute( } } - val systemUiController = rememberSystemUiController() - SideEffect { - systemUiController.setStatusBarColor( - color = White - ) - systemUiController.setNavigationBarColor( - color = White - ) - } - - val lifecycleOwner = LocalLifecycleOwner.current - val context = LocalContext.current - - val amplitudeTracker = LocalTracker.current - LaunchedEffect(key1 = true) { viewModel.getProfile() viewModel.getFilteringInfo() @@ -127,6 +110,9 @@ fun HomeRoute( viewModel.getRecommendInternFlow() } + val lifecycleOwner = LocalLifecycleOwner.current + val context = LocalContext.current + LaunchedEffect(viewModel.homeSideEffect, lifecycleOwner) { viewModel.homeSideEffect.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle) .collect { sideEffect -> @@ -138,6 +124,8 @@ fun HomeRoute( } } + val amplitudeTracker = LocalTracker.current + HomeScreen( paddingValues = paddingValues, navigateToIntern = { diff --git a/feature/home/src/main/java/com/terning/feature/home/navigation/HometNavigation.kt b/feature/home/src/main/java/com/terning/feature/home/navigation/HometNavigation.kt index 57996f9e2..3108a889e 100644 --- a/feature/home/src/main/java/com/terning/feature/home/navigation/HometNavigation.kt +++ b/feature/home/src/main/java/com/terning/feature/home/navigation/HometNavigation.kt @@ -1,10 +1,14 @@ package com.terning.feature.home.navigation +import android.os.Build +import androidx.annotation.RequiresApi import androidx.compose.foundation.layout.PaddingValues import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable +import androidx.navigation.navDeepLink +import com.terning.core.designsystem.util.DeeplinkDefaults import com.terning.core.navigation.MainTabRoute import com.terning.feature.home.HomeRoute import kotlinx.serialization.Serializable @@ -16,12 +20,19 @@ fun NavController.navigateHome(navOptions: NavOptions? = null) { ) } +@RequiresApi(Build.VERSION_CODES.TIRAMISU) fun NavGraphBuilder.homeNavGraph( paddingValues: PaddingValues, navigateToCalendar: () -> Unit, navigateToIntern: (Long) -> Unit ) { - composable { + composable( + deepLinks = listOf( + navDeepLink( + basePath = DeeplinkDefaults.build("home") + ) + ) + ) { HomeRoute( paddingValues = paddingValues, navigateToCalendar = navigateToCalendar, diff --git a/feature/main/build.gradle.kts b/feature/main/build.gradle.kts index 97106181c..79698c6ef 100644 --- a/feature/main/build.gradle.kts +++ b/feature/main/build.gradle.kts @@ -11,6 +11,8 @@ android { dependencies { // core implementation(projects.core.navigator) + implementation(projects.core.firebase) + implementation(projects.core.designsystem) // feature implementation(projects.feature.calendar) diff --git a/feature/main/src/main/java/com/terning/feature/main/MainActivity.kt b/feature/main/src/main/java/com/terning/feature/main/MainActivity.kt index bc056217c..1231edb91 100644 --- a/feature/main/src/main/java/com/terning/feature/main/MainActivity.kt +++ b/feature/main/src/main/java/com/terning/feature/main/MainActivity.kt @@ -12,6 +12,7 @@ import androidx.compose.runtime.CompositionLocalProvider import com.terning.core.analytics.AmplitudeTracker import com.terning.core.analytics.LocalTracker import com.terning.core.designsystem.theme.TerningPointTheme +import com.terning.core.designsystem.util.DeeplinkDefaults.REDIRECT import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject @@ -28,10 +29,12 @@ class MainActivity : ComponentActivity() { setContent { val navigator: MainNavigator = rememberMainNavigator() val redirect: String? = intent.data?.getQueryParameter(REDIRECT) + val host: String? = intent.data?.host TerningPointTheme { CompositionLocalProvider(LocalTracker provides tracker) { MainScreen( + host = host, redirect = redirect, navigator = navigator ) @@ -41,8 +44,6 @@ class MainActivity : ComponentActivity() { } companion object { - private const val REDIRECT: String = "redirect" - fun getIntent( context: Context, ) = Intent(context, MainActivity::class.java) diff --git a/feature/main/src/main/java/com/terning/feature/main/MainNavigator.kt b/feature/main/src/main/java/com/terning/feature/main/MainNavigator.kt index e24ad623d..9fd4f965f 100644 --- a/feature/main/src/main/java/com/terning/feature/main/MainNavigator.kt +++ b/feature/main/src/main/java/com/terning/feature/main/MainNavigator.kt @@ -8,9 +8,13 @@ import androidx.navigation.NavHostController import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import androidx.navigation.navOptions +import com.terning.core.designsystem.type.NotificationRedirect +import com.terning.feature.calendar.calendar.navigation.Calendar import com.terning.feature.calendar.calendar.navigation.navigateCalendar +import com.terning.feature.home.navigation.Home import com.terning.feature.home.navigation.navigateHome import com.terning.feature.mypage.mypage.navigation.navigateMyPage +import com.terning.feature.search.search.navigation.Search import com.terning.feature.search.search.navigation.navigateSearch import com.terning.feature.splash.navigation.Splash @@ -22,7 +26,13 @@ class MainNavigator( @Composable get() = navController .currentBackStackEntryAsState().value?.destination - fun getStartDestination(redirect: String?) = Splash(redirect = redirect) + fun getStartDestination(redirect: String?, host: String?) = + when (NotificationRedirect.from(host)) { + NotificationRedirect.SEARCH -> Search + NotificationRedirect.HOME -> Home + NotificationRedirect.CALENDAR -> Calendar + else -> Splash(redirect) + } val currentTab: MainTab? @Composable get() = MainTab.find { tab -> diff --git a/feature/main/src/main/java/com/terning/feature/main/MainScreen.kt b/feature/main/src/main/java/com/terning/feature/main/MainScreen.kt index 3a380111e..2dbbb7f53 100644 --- a/feature/main/src/main/java/com/terning/feature/main/MainScreen.kt +++ b/feature/main/src/main/java/com/terning/feature/main/MainScreen.kt @@ -51,6 +51,7 @@ import com.terning.feature.onboarding.signin.navigation.navigateSignIn import com.terning.feature.onboarding.signin.navigation.signInNavGraph import com.terning.feature.onboarding.signup.navigation.navigateSignUp import com.terning.feature.onboarding.signup.navigation.signUpNavGraph +import com.terning.feature.search.search.navigation.navigateSearch import com.terning.feature.search.search.navigation.searchNavGraph import com.terning.feature.search.searchprocess.navigation.navigateSearchProcess import com.terning.feature.search.searchprocess.navigation.searchProcessNavGraph @@ -62,18 +63,16 @@ import kotlinx.coroutines.launch @RequiresApi(Build.VERSION_CODES.TIRAMISU) @Composable fun MainScreen( + host: String?, redirect: String?, navigator: MainNavigator = rememberMainNavigator(), ) { val context = LocalContext.current var backPressedState by remember { mutableStateOf(true) } var backPressedTime = 0L - val snackBarHostState = remember { SnackbarHostState() } val coroutineScope = rememberCoroutineScope() - val amplitudeTracker = LocalTracker.current - BackHandler(enabled = backPressedState) { if (System.currentTimeMillis() - backPressedTime <= 3000) { (context as Activity).finish() @@ -89,6 +88,12 @@ fun MainScreen( backPressedTime = System.currentTimeMillis() } + val amplitudeTracker = LocalTracker.current + val splashNavOptions = NavOptions.Builder().setPopUpTo( + route = Splash(redirect), + inclusive = true + ).build() + Scaffold( snackbarHost = { SnackbarHost( @@ -140,25 +145,21 @@ fun MainScreen( ExitTransition.None }, navController = navigator.navController, - startDestination = navigator.getStartDestination(redirect) + startDestination = navigator.getStartDestination(redirect = redirect, host = host) ) { splashNavGraph( navigateHome = { - navigator.navController.navigateHome( - navOptions = NavOptions.Builder().setPopUpTo( - route = Splash(redirect), - inclusive = true - ).build() - ) + navigator.navController.navigateHome(navOptions = splashNavOptions) }, navigateSignIn = { - navigator.navController.navigateSignIn( - navOptions = NavOptions.Builder().setPopUpTo( - route = Splash(redirect), - inclusive = true - ).build() - ) + navigator.navController.navigateSignIn(navOptions = splashNavOptions) }, + navigateCalendar = { + navigator.navController.navigateCalendar(navOptions = splashNavOptions) + }, + navigateSearch = { + navigator.navController.navigateSearch(navOptions = splashNavOptions) + } ) homeNavGraph( paddingValues = paddingValues, diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt index 13c438bdc..c80f7b245 100644 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt @@ -28,7 +28,6 @@ import androidx.compose.material3.VerticalDivider import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -107,17 +106,13 @@ fun MyPageRoute( viewModel.updateAlarmAvailability(isGranted) } - SideEffect { - systemUiController.setStatusBarColor( - color = Back - ) + LaunchedEffect(Unit) { + systemUiController.setStatusBarColor(color = Back) } DisposableEffect(lifecycleOwner) { onDispose { - systemUiController.setStatusBarColor( - color = White - ) + systemUiController.setStatusBarColor(color = White) } } diff --git a/feature/mypage/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditRoute.kt b/feature/mypage/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditRoute.kt index e3fae490b..78f09f9a7 100644 --- a/feature/mypage/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditRoute.kt +++ b/feature/mypage/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditRoute.kt @@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -54,10 +53,8 @@ fun ProfileEditRoute( val systemUiController = rememberSystemUiController() - SideEffect { - systemUiController.setStatusBarColor( - color = White - ) + LaunchedEffect(Unit) { + systemUiController.setStatusBarColor(color = White) } LaunchedEffect(key1 = true) { diff --git a/feature/search/src/main/java/com/terning/feature/search/search/navigation/SearchNavigation.kt b/feature/search/src/main/java/com/terning/feature/search/search/navigation/SearchNavigation.kt index f3be18a91..7156f0642 100644 --- a/feature/search/src/main/java/com/terning/feature/search/search/navigation/SearchNavigation.kt +++ b/feature/search/src/main/java/com/terning/feature/search/search/navigation/SearchNavigation.kt @@ -5,6 +5,8 @@ import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable +import androidx.navigation.navDeepLink +import com.terning.core.designsystem.util.DeeplinkDefaults import com.terning.core.navigation.MainTabRoute import com.terning.feature.search.search.SearchRoute import kotlinx.serialization.Serializable @@ -21,7 +23,13 @@ fun NavGraphBuilder.searchNavGraph( navigateSearchProcess: () -> Unit, navigateIntern: (Long) -> Unit, ) { - composable { + composable( + deepLinks = listOf( + navDeepLink( + basePath = DeeplinkDefaults.build("search") + ) + ) + ) { SearchRoute( paddingValues = paddingValues, navigateToSearchProcess = navigateSearchProcess, diff --git a/feature/splash/src/main/java/com/terning/feature/splash/SplashRoute.kt b/feature/splash/src/main/java/com/terning/feature/splash/SplashRoute.kt index d97f3746f..49a5fbbc0 100644 --- a/feature/splash/src/main/java/com/terning/feature/splash/SplashRoute.kt +++ b/feature/splash/src/main/java/com/terning/feature/splash/SplashRoute.kt @@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext @@ -28,6 +27,8 @@ import com.terning.core.designsystem.extension.getVersionName import com.terning.core.designsystem.extension.launchPlayStore import com.terning.core.designsystem.theme.TerningMain import com.terning.core.designsystem.theme.TerningPointTheme +import com.terning.core.designsystem.theme.White +import com.terning.core.designsystem.type.NotificationRedirect import com.terning.domain.update.entity.UpdateState import com.terning.feature.splash.component.TerningMajorUpdateDialog import com.terning.feature.splash.component.TerningPatchUpdateDialog @@ -38,20 +39,26 @@ internal fun SplashRoute( redirect: String?, navigateToHome: () -> Unit, navigateToSignIn: () -> Unit, + navigateToCalendar: () -> Unit, + navigateToSearch: () -> Unit, viewModel: SplashViewModel = hiltViewModel(), ) { - val systemUiController = rememberSystemUiController() val lifecycleOwner = LocalLifecycleOwner.current val context = LocalContext.current val updateState by viewModel.updateState.collectAsStateWithLifecycle() - SideEffect { - systemUiController.setStatusBarColor( - color = TerningMain - ) - systemUiController.setNavigationBarColor( - color = TerningMain - ) + val systemUiController = rememberSystemUiController() + + LaunchedEffect(Unit) { + systemUiController.setStatusBarColor(color = TerningMain) + systemUiController.setNavigationBarColor(color = TerningMain) + } + + DisposableEffect(lifecycleOwner) { + onDispose { + systemUiController.setStatusBarColor(color = White) + systemUiController.setNavigationBarColor(color = White) + } } DisposableEffect(lifecycleOwner) { @@ -77,8 +84,20 @@ internal fun SplashRoute( .collect { sideEffect -> when (sideEffect) { is SplashSideEffect.HasAccessToken -> { - if (sideEffect.hasAccessToken) navigateToHome() - else navigateToSignIn() + if (sideEffect.hasAccessToken) { + if (redirect.isNullOrBlank()) { + navigateToHome() + } else { + when (NotificationRedirect.from(redirect)) { + NotificationRedirect.CALENDAR -> navigateToCalendar() + NotificationRedirect.HOME -> navigateToHome() + NotificationRedirect.SEARCH -> navigateToSearch() + else -> navigateToHome() + } + } + } else { + navigateToSignIn() + } } } } diff --git a/feature/splash/src/main/java/com/terning/feature/splash/navigation/SplashNavigation.kt b/feature/splash/src/main/java/com/terning/feature/splash/navigation/SplashNavigation.kt index 183dd5c4a..301103528 100644 --- a/feature/splash/src/main/java/com/terning/feature/splash/navigation/SplashNavigation.kt +++ b/feature/splash/src/main/java/com/terning/feature/splash/navigation/SplashNavigation.kt @@ -4,21 +4,22 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import androidx.navigation.navDeepLink import androidx.navigation.toRoute +import com.terning.core.designsystem.util.DeeplinkDefaults import com.terning.core.navigation.Route import com.terning.feature.splash.SplashRoute import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -private const val SPLASH_PATH: String = "terning://splash" - fun NavGraphBuilder.splashNavGraph( navigateHome: () -> Unit, navigateSignIn: () -> Unit, + navigateSearch: () -> Unit, + navigateCalendar: () -> Unit ) { composable( deepLinks = listOf( navDeepLink( - basePath = SPLASH_PATH + basePath = DeeplinkDefaults.build("splash") ) ) ) { @@ -27,6 +28,8 @@ fun NavGraphBuilder.splashNavGraph( redirect = args.redirect, navigateToHome = navigateHome, navigateToSignIn = navigateSignIn, + navigateToSearch = navigateSearch, + navigateToCalendar = navigateCalendar ) } }