Add network connectivity check before launching Chrome Custom Tab

pull/2111/head
santi-pine03 2 weeks ago
parent 7d45eae4f8
commit c73328f22f

@ -74,7 +74,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.theme.GradientColo
import com.google.samples.apps.nowinandroid.core.designsystem.theme.LocalGradientColors
import com.google.samples.apps.nowinandroid.core.navigation.Navigator
import com.google.samples.apps.nowinandroid.core.navigation.toEntries
import com.google.samples.apps.nowinandroid.feature.bookmarks.impl.navigation.LocalSnackbarHostState
import com.google.samples.apps.nowinandroid.core.ui.LocalSnackbarHostState
import com.google.samples.apps.nowinandroid.feature.bookmarks.impl.navigation.bookmarksEntry
import com.google.samples.apps.nowinandroid.feature.foryou.api.navigation.ForYouNavKey
import com.google.samples.apps.nowinandroid.feature.foryou.impl.navigation.forYouEntry
@ -83,6 +83,7 @@ import com.google.samples.apps.nowinandroid.feature.search.api.navigation.Search
import com.google.samples.apps.nowinandroid.feature.search.impl.navigation.searchEntry
import com.google.samples.apps.nowinandroid.feature.settings.impl.SettingsDialog
import com.google.samples.apps.nowinandroid.feature.topic.impl.navigation.topicEntry
import com.google.samples.apps.nowinandroid.core.ui.LocalIsOffline
import com.google.samples.apps.nowinandroid.navigation.TOP_LEVEL_NAV_ITEMS
import com.google.samples.apps.nowinandroid.feature.settings.impl.R as settingsR
@ -117,7 +118,10 @@ fun NiaApp(
)
}
}
CompositionLocalProvider(LocalSnackbarHostState provides snackbarHostState) {
CompositionLocalProvider(
LocalSnackbarHostState provides snackbarHostState,
LocalIsOffline provides isOffline,
) {
NiaApp(
appState = appState,

@ -0,0 +1,21 @@
/*
* Copyright 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.ui
import androidx.compose.runtime.compositionLocalOf
val LocalIsOffline = compositionLocalOf { false }

@ -0,0 +1,24 @@
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.ui
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.compositionLocalOf
val LocalSnackbarHostState = compositionLocalOf<SnackbarHostState> {
error("SnackbarHostState should be initialized at runtime")
}

@ -18,6 +18,7 @@ package com.google.samples.apps.nowinandroid.core.ui
import android.content.Context
import android.net.Uri
import android.widget.Toast
import androidx.annotation.ColorInt
import androidx.browser.customtabs.CustomTabColorSchemeParams
import androidx.browser.customtabs.CustomTabsIntent
@ -62,18 +63,26 @@ fun LazyStaggeredGridScope.newsFeed(
val context = LocalContext.current
val analyticsHelper = LocalAnalyticsHelper.current
val backgroundColor = MaterialTheme.colorScheme.background.toArgb()
val isOffline = LocalIsOffline.current
NewsResourceCardExpanded(
userNewsResource = userNewsResource,
isBookmarked = userNewsResource.isSaved,
onClick = {
onExpandedCardClick()
analyticsHelper.logNewsResourceOpened(
newsResourceId = userNewsResource.id,
)
launchCustomChromeTab(context, Uri.parse(userNewsResource.url), backgroundColor)
onNewsResourceViewed(userNewsResource.id)
if (isOffline) {
Toast.makeText(
context,
context.getString(R.string.core_ui_not_connected),
Toast.LENGTH_SHORT,
).show()
} else {
onExpandedCardClick()
analyticsHelper.logNewsResourceOpened(
newsResourceId = userNewsResource.id,
)
launchCustomChromeTab(context, Uri.parse(userNewsResource.url), backgroundColor)
onNewsResourceViewed(userNewsResource.id)
}
},
hasBeenViewed = userNewsResource.hasBeenViewed,
onToggleBookmark = {

@ -17,6 +17,7 @@
package com.google.samples.apps.nowinandroid.core.ui
import android.net.Uri
import android.widget.Toast
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.MaterialTheme
@ -47,6 +48,7 @@ fun LazyListScope.userNewsResourceCardItems(
val backgroundColor = MaterialTheme.colorScheme.background.toArgb()
val context = LocalContext.current
val analyticsHelper = LocalAnalyticsHelper.current
val isOffline = LocalIsOffline.current
NewsResourceCardExpanded(
userNewsResource = userNewsResource,
@ -54,11 +56,19 @@ fun LazyListScope.userNewsResourceCardItems(
hasBeenViewed = userNewsResource.hasBeenViewed,
onToggleBookmark = { onToggleBookmark(userNewsResource) },
onClick = {
analyticsHelper.logNewsResourceOpened(
newsResourceId = userNewsResource.id,
)
launchCustomChromeTab(context, resourceUrl, backgroundColor)
onNewsResourceViewed(userNewsResource.id)
if (isOffline) {
Toast.makeText(
context,
context.getString(R.string.core_ui_not_connected),
Toast.LENGTH_SHORT,
).show()
} else {
analyticsHelper.logNewsResourceOpened(
newsResourceId = userNewsResource.id,
)
launchCustomChromeTab(context, resourceUrl, backgroundColor)
onNewsResourceViewed(userNewsResource.id)
}
},
onTopicClick = onTopicClick,
modifier = itemModifier,

@ -31,4 +31,5 @@
<string name="core_ui_interests_card_unfollow_button_content_desc">Unfollow interest</string>
<string name="core_ui_feed_sharing">Feed sharing</string>
<string name="core_ui_feed_sharing_data">%1$s: %2$s</string>
<string name="core_ui_not_connected">Can\'t open, no internet connection</string>
</resources>

@ -17,9 +17,8 @@
package com.google.samples.apps.nowinandroid.feature.bookmarks.impl.navigation
import androidx.compose.material3.SnackbarDuration.Short
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.SnackbarResult.ActionPerformed
import androidx.compose.runtime.compositionLocalOf
import com.google.samples.apps.nowinandroid.core.ui.LocalSnackbarHostState
import androidx.navigation3.runtime.EntryProviderScope
import androidx.navigation3.runtime.NavKey
import com.google.samples.apps.nowinandroid.core.navigation.Navigator
@ -43,7 +42,3 @@ fun EntryProviderScope<NavKey>.bookmarksEntry(navigator: Navigator) {
}
}
// TODO: Why is this here?
val LocalSnackbarHostState = compositionLocalOf<SnackbarHostState> {
error("SnackbarHostState state should be initialized at runtime")
}

Loading…
Cancel
Save