From 6831c549a74352c809eede2e68774aed5dfbc642 Mon Sep 17 00:00:00 2001 From: TM Date: Wed, 22 May 2024 02:41:36 -0700 Subject: [PATCH] Add errorMessage implementation for custom tab launch error --- .../apps/nowinandroid/navigation/NiaNavHost.kt | 2 ++ .../google/samples/apps/nowinandroid/ui/NiaApp.kt | 1 + .../samples/apps/nowinandroid/core/ui/NewsFeed.kt | 12 +++++++++--- .../nowinandroid/core/ui/NewsResourceCardList.kt | 3 ++- .../apps/nowinandroid/feature/search/SearchScreen.kt | 11 +++++++++++ .../feature/search/navigation/SearchNavigation.kt | 2 ++ 6 files changed, 27 insertions(+), 4 deletions(-) diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/navigation/NiaNavHost.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/navigation/NiaNavHost.kt index 39bc03de7..8c6393eb7 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/navigation/NiaNavHost.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/navigation/NiaNavHost.kt @@ -39,6 +39,7 @@ import com.google.samples.apps.nowinandroid.ui.interests2pane.interestsListDetai fun NiaNavHost( appState: NiaAppState, onShowSnackbar: suspend (String, String?) -> Boolean, + errorHandler: (String) -> Unit, modifier: Modifier = Modifier, startDestination: String = FOR_YOU_ROUTE, ) { @@ -57,6 +58,7 @@ fun NiaNavHost( onBackClick = navController::popBackStack, onInterestsClick = { appState.navigateToTopLevelDestination(INTERESTS) }, onTopicClick = navController::navigateToInterests, + errorHandler = errorHandler, ) interestsListDetailScreen() } diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt index 87b4837f4..0b73b463d 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt @@ -232,6 +232,7 @@ internal fun NiaApp( duration = Short, ) == ActionPerformed }, + errorHandler = { message -> appState.addErrorMessage(message) } ) } } diff --git a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt index afdb584a2..cc03e5eba 100644 --- a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt +++ b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt @@ -16,6 +16,7 @@ package com.google.samples.apps.nowinandroid.core.ui +import android.content.ActivityNotFoundException import android.content.Context import android.net.Uri import androidx.annotation.ColorInt @@ -52,6 +53,7 @@ fun LazyStaggeredGridScope.newsFeed( onNewsResourceViewed: (String) -> Unit, onTopicClick: (String) -> Unit, onExpandedCardClick: () -> Unit = {}, + onLaunchFailed: () -> Unit = {}, ) { when (feedState) { NewsFeedUiState.Loading -> Unit @@ -73,7 +75,7 @@ fun LazyStaggeredGridScope.newsFeed( analyticsHelper.logNewsResourceOpened( newsResourceId = userNewsResource.id, ) - launchCustomChromeTab(context, Uri.parse(userNewsResource.url), backgroundColor) + launchCustomChromeTab(context, Uri.parse(userNewsResource.url), backgroundColor, onLaunchFailed) onNewsResourceViewed(userNewsResource.id) }, @@ -94,14 +96,18 @@ fun LazyStaggeredGridScope.newsFeed( } } -fun launchCustomChromeTab(context: Context, uri: Uri, @ColorInt toolbarColor: Int) { +fun launchCustomChromeTab(context: Context, uri: Uri, @ColorInt toolbarColor: Int, onLaunchFailed: () -> Unit) { val customTabBarColor = CustomTabColorSchemeParams.Builder() .setToolbarColor(toolbarColor).build() val customTabsIntent = CustomTabsIntent.Builder() .setDefaultColorSchemeParams(customTabBarColor) .build() - customTabsIntent.launchUrl(context, uri) + try { + customTabsIntent.launchUrl(context, uri) + } catch (e: ActivityNotFoundException) { + onLaunchFailed() + } } /** diff --git a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt index ea1c09d01..2967a0c6e 100644 --- a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt +++ b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt @@ -38,6 +38,7 @@ fun LazyListScope.userNewsResourceCardItems( onToggleBookmark: (item: UserNewsResource) -> Unit, onNewsResourceViewed: (String) -> Unit, onTopicClick: (String) -> Unit, + onLaunchFailed: () -> Unit = {}, itemModifier: Modifier = Modifier, ) = items( items = items, @@ -57,7 +58,7 @@ fun LazyListScope.userNewsResourceCardItems( analyticsHelper.logNewsResourceOpened( newsResourceId = userNewsResource.id, ) - launchCustomChromeTab(context, resourceUrl, backgroundColor) + launchCustomChromeTab(context, resourceUrl, backgroundColor, onLaunchFailed) onNewsResourceViewed(userNewsResource.id) }, onTopicClick = onTopicClick, diff --git a/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt b/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt index 86b1eb717..21baf4130 100644 --- a/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt +++ b/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt @@ -101,10 +101,14 @@ internal fun SearchRoute( onTopicClick: (String) -> Unit, modifier: Modifier = Modifier, searchViewModel: SearchViewModel = hiltViewModel(), + errorHandler: (String) -> Unit, ) { val recentSearchQueriesUiState by searchViewModel.recentSearchQueriesUiState.collectAsStateWithLifecycle() val searchResultUiState by searchViewModel.searchResultUiState.collectAsStateWithLifecycle() val searchQuery by searchViewModel.searchQuery.collectAsStateWithLifecycle() + + val launchFailedString = stringResource(id = searchR.string.feature_search_custom_tab_activity_not_found) + SearchScreen( modifier = modifier, searchQuery = searchQuery, @@ -119,6 +123,7 @@ internal fun SearchRoute( onBackClick = onBackClick, onInterestsClick = onInterestsClick, onTopicClick = onTopicClick, + onLaunchFailed = { errorHandler(launchFailedString) }, ) } @@ -137,6 +142,7 @@ internal fun SearchScreen( onBackClick: () -> Unit = {}, onInterestsClick: () -> Unit = {}, onTopicClick: (String) -> Unit = {}, + onLaunchFailed: () -> Unit = {}, ) { TrackScreenViewEvent(screenName = "Search") Column(modifier = modifier) { @@ -193,6 +199,7 @@ internal fun SearchScreen( onNewsResourcesCheckedChanged = onNewsResourcesCheckedChanged, onNewsResourceViewed = onNewsResourceViewed, onFollowButtonClick = onFollowButtonClick, + onLaunchFailed = onLaunchFailed, ) } } @@ -287,6 +294,7 @@ private fun SearchResultBody( onNewsResourcesCheckedChanged: (String, Boolean) -> Unit, onNewsResourceViewed: (String) -> Unit, onFollowButtonClick: (String, Boolean) -> Unit, + onLaunchFailed: () -> Unit, ) { val state = rememberLazyStaggeredGridState() Box( @@ -361,6 +369,9 @@ private fun SearchResultBody( onExpandedCardClick = { onSearchTriggered(searchQuery) }, + onLaunchFailed = { + onLaunchFailed() + } ) } } diff --git a/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/navigation/SearchNavigation.kt b/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/navigation/SearchNavigation.kt index 81f3576b4..02470b092 100644 --- a/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/navigation/SearchNavigation.kt +++ b/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/navigation/SearchNavigation.kt @@ -30,6 +30,7 @@ fun NavGraphBuilder.searchScreen( onBackClick: () -> Unit, onInterestsClick: () -> Unit, onTopicClick: (String) -> Unit, + errorHandler: (String) -> Unit, ) { // TODO: Handle back stack for each top-level destination. At the moment each top-level // destination may have own search screen's back stack. @@ -38,6 +39,7 @@ fun NavGraphBuilder.searchScreen( onBackClick = onBackClick, onInterestsClick = onInterestsClick, onTopicClick = onTopicClick, + errorHandler = errorHandler ) } }