Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
6dc59e7
Use SafeArgs navigation for Topic feature
dturner May 1, 2024
d96bcf8
Migrate Interests nested NavHost to safe args
dturner May 3, 2024
4909972
Update to alpha08, use toRoute to obtain destination inside VM
dturner May 3, 2024
89163b5
Migrate remainder of app to type-safe navigation
dturner May 3, 2024
9779074
Remove Interests2PaneViewModel as it was overkill for holding a singl…
dturner May 3, 2024
29e08ea
Add deeplink action to enable testing from terminal
dturner May 3, 2024
2d45b84
Merge branch 'main' into dt/nav-safe-args
dturner May 3, 2024
924391c
Fix spotless
dturner May 3, 2024
0f926ba
🤖 Updates baselines for Dependency Guard
dturner May 3, 2024
8cc0fc0
🤖 Updates screenshots
dturner May 3, 2024
116e961
Change startDestination from KClass to default instance
dturner May 3, 2024
2264451
Use navigation argument topicId as default value to InterestListDetai…
dturner May 3, 2024
7ec21d9
Fix issue where selected topic in list was not showing as selected. M…
dturner May 7, 2024
f67f4d1
Update ForYou destination to match current deeplink pattern
dturner May 8, 2024
93a48a2
Use version catalog reference to serialization plugin
dturner May 8, 2024
173ac67
Remove autoVerify from intent filter
dturner May 8, 2024
3cff2fb
Remove unnecessary comment
dturner May 8, 2024
4a84cf2
Add specific type for deeplinks
dturner May 8, 2024
f711e69
Merge branch 'main' into dt/nav-safe-args (AnimatedPane broken)
dturner May 9, 2024
68152e5
Update to adaptive alpha12, fix merge issues
dturner May 14, 2024
aba2b2c
Remove different deeplink destination, add route for nested nav host
dturner May 14, 2024
be752e7
Fix tests, fix spotless
dturner May 14, 2024
8fc2e15
Update to navigation 2.8.0-beta01
dturner May 16, 2024
041e46e
Merge branch 'main' into dt/nav-safe-args
dturner May 30, 2024
da8f32a
Rename Destinations to Routes
dturner May 30, 2024
a6397b7
Merge branch 'main' into dt/nav-safe-args
dturner May 30, 2024
b73ee6d
🤖 Updates baselines for Dependency Guard
dturner May 30, 2024
95bdc0f
Rename ForYouRoute composable to ForYouScreen
dturner May 30, 2024
ec71b2a
Add Robolectric to allow ViewModel tests to pass
dturner Jun 25, 2024
fc58680
Remove string-based argument name from navigation code
dturner Jul 19, 2024
e19c315
Tidy up top level destination handling
dturner Sep 3, 2024
00efda5
Merge branch 'main' into dt/nav-safe-args
dturner Sep 4, 2024
4b3f537
Clean up deep link handling
dturner Sep 4, 2024
2d34cb0
Merge branch 'main' into dt/nav-safe-args
dturner Sep 4, 2024
a8ffd1f
Fix incorrect deep link key name in ForYouViewModelTest
dturner Sep 4, 2024
8d57134
Fix spotless
dturner Sep 4, 2024
5429056
🤖 Updates baselines for Dependency Guard
dturner Sep 4, 2024
4ff5b1f
Fix failing InterestsListDetailScreenTest
dturner Sep 4, 2024
bee8c88
Update feature/interests/src/test/kotlin/com/google/samples/apps/nowi…
dturner Sep 4, 2024
72cab94
Update to navigation 2.8.0 stable
dturner Sep 5, 2024
651f94e
Update badging
dturner Sep 5, 2024
6cf8db2
Merge branch 'main' into dt/nav-safe-args
dturner Sep 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ plugins {
id("com.google.android.gms.oss-licenses-plugin")
alias(libs.plugins.baselineprofile)
alias(libs.plugins.roborazzi)
alias(libs.plugins.kotlin.serialization)
}

android {
Expand Down Expand Up @@ -103,6 +104,7 @@ dependencies {
implementation(libs.androidx.window.core)
implementation(libs.kotlinx.coroutines.guava)
implementation(libs.coil.kt)
implementation(libs.kotlinx.serialization.json)

ksp(libs.hilt.compiler)

Expand Down
72 changes: 36 additions & 36 deletions app/dependencies/prodReleaseRuntimeClasspath.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@ androidx.activity:activity-compose:1.8.2
androidx.activity:activity-ktx:1.8.2
androidx.activity:activity:1.8.2
androidx.annotation:annotation-experimental:1.4.1
androidx.annotation:annotation-jvm:1.8.0
androidx.annotation:annotation:1.8.0
androidx.annotation:annotation-jvm:1.8.1
androidx.annotation:annotation:1.8.1
androidx.appcompat:appcompat-resources:1.7.0
androidx.appcompat:appcompat:1.7.0
androidx.arch.core:core-common:2.2.0
androidx.arch.core:core-runtime:2.2.0
androidx.autofill:autofill:1.0.0
androidx.browser:browser:1.8.0
androidx.collection:collection-jvm:1.4.0
androidx.collection:collection-ktx:1.4.0
androidx.collection:collection:1.4.0
androidx.compose.animation:animation-android:1.7.0-rc01
androidx.compose.animation:animation-core-android:1.7.0-rc01
androidx.compose.animation:animation-core:1.7.0-rc01
androidx.compose.animation:animation:1.7.0-rc01
androidx.compose.foundation:foundation-android:1.7.0-rc01
androidx.compose.foundation:foundation-layout-android:1.7.0-rc01
androidx.compose.foundation:foundation-layout:1.7.0-rc01
androidx.compose.foundation:foundation:1.7.0-rc01
androidx.collection:collection-jvm:1.4.2
androidx.collection:collection-ktx:1.4.2
androidx.collection:collection:1.4.2
androidx.compose.animation:animation-android:1.7.0
androidx.compose.animation:animation-core-android:1.7.0
androidx.compose.animation:animation-core:1.7.0
androidx.compose.animation:animation:1.7.0
androidx.compose.foundation:foundation-android:1.7.0
androidx.compose.foundation:foundation-layout-android:1.7.0
androidx.compose.foundation:foundation-layout:1.7.0
androidx.compose.foundation:foundation:1.7.0
androidx.compose.material3.adaptive:adaptive-android:1.0.0-rc01
androidx.compose.material3.adaptive:adaptive-layout-android:1.0.0-rc01
androidx.compose.material3.adaptive:adaptive-layout:1.0.0-rc01
Expand All @@ -39,25 +39,25 @@ androidx.compose.material:material-icons-extended-android:1.6.3
androidx.compose.material:material-icons-extended:1.6.3
androidx.compose.material:material-ripple-android:1.7.0-rc01
androidx.compose.material:material-ripple:1.7.0-rc01
androidx.compose.runtime:runtime-android:1.7.0-rc01
androidx.compose.runtime:runtime-saveable-android:1.7.0-rc01
androidx.compose.runtime:runtime-saveable:1.7.0-rc01
androidx.compose.runtime:runtime-android:1.7.0
androidx.compose.runtime:runtime-saveable-android:1.7.0
androidx.compose.runtime:runtime-saveable:1.7.0
androidx.compose.runtime:runtime-tracing:1.0.0-beta01
androidx.compose.runtime:runtime:1.7.0-rc01
androidx.compose.ui:ui-android:1.7.0-rc01
androidx.compose.ui:ui-geometry-android:1.7.0-rc01
androidx.compose.ui:ui-geometry:1.7.0-rc01
androidx.compose.ui:ui-graphics-android:1.7.0-rc01
androidx.compose.ui:ui-graphics:1.7.0-rc01
androidx.compose.ui:ui-text-android:1.7.0-rc01
androidx.compose.ui:ui-text:1.7.0-rc01
androidx.compose.ui:ui-tooling-preview-android:1.7.0-rc01
androidx.compose.ui:ui-tooling-preview:1.7.0-rc01
androidx.compose.ui:ui-unit-android:1.7.0-rc01
androidx.compose.ui:ui-unit:1.7.0-rc01
androidx.compose.ui:ui-util-android:1.7.0-rc01
androidx.compose.ui:ui-util:1.7.0-rc01
androidx.compose.ui:ui:1.7.0-rc01
androidx.compose.runtime:runtime:1.7.0
androidx.compose.ui:ui-android:1.7.0
androidx.compose.ui:ui-geometry-android:1.7.0
androidx.compose.ui:ui-geometry:1.7.0
androidx.compose.ui:ui-graphics-android:1.7.0
androidx.compose.ui:ui-graphics:1.7.0
androidx.compose.ui:ui-text-android:1.7.0
androidx.compose.ui:ui-text:1.7.0
androidx.compose.ui:ui-tooling-preview-android:1.7.0
androidx.compose.ui:ui-tooling-preview:1.7.0
androidx.compose.ui:ui-unit-android:1.7.0
androidx.compose.ui:ui-unit:1.7.0
androidx.compose.ui:ui-util-android:1.7.0
androidx.compose.ui:ui-util:1.7.0
androidx.compose.ui:ui:1.7.0
androidx.compose:compose-bom:2024.02.02
androidx.concurrent:concurrent-futures:1.1.0
androidx.core:core-ktx:1.13.1
Expand Down Expand Up @@ -106,11 +106,11 @@ androidx.lifecycle:lifecycle-viewmodel:2.8.3
androidx.loader:loader:1.0.0
androidx.localbroadcastmanager:localbroadcastmanager:1.0.0
androidx.metrics:metrics-performance:1.0.0-alpha04
androidx.navigation:navigation-common-ktx:2.8.0-beta06
androidx.navigation:navigation-common:2.8.0-beta06
androidx.navigation:navigation-compose:2.8.0-beta06
androidx.navigation:navigation-runtime-ktx:2.8.0-beta06
androidx.navigation:navigation-runtime:2.8.0-beta06
androidx.navigation:navigation-common-ktx:2.8.0
androidx.navigation:navigation-common:2.8.0
androidx.navigation:navigation-compose:2.8.0
androidx.navigation:navigation-runtime-ktx:2.8.0
androidx.navigation:navigation-runtime:2.8.0
androidx.print:print:1.0.0
androidx.privacysandbox.ads:ads-adservices-java:1.0.0-beta05
androidx.privacysandbox.ads:ads-adservices:1.0.0-beta05
Expand Down
10 changes: 7 additions & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<data
android:scheme="https"
android:host="www.nowinandroid.apps.samples.google.com" />
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data android:scheme="https" />
<data android:host="www.nowinandroid.apps.samples.google.com" />
</intent-filter>
</activity>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.compose.NavHost
import com.google.samples.apps.nowinandroid.feature.bookmarks.navigation.bookmarksScreen
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.FOR_YOU_ROUTE
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.ForYouRoute
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.forYouScreen
import com.google.samples.apps.nowinandroid.feature.interests.navigation.navigateToInterests
import com.google.samples.apps.nowinandroid.feature.search.navigation.searchScreen
Expand All @@ -40,12 +40,11 @@ fun NiaNavHost(
appState: NiaAppState,
onShowSnackbar: suspend (String, String?) -> Boolean,
modifier: Modifier = Modifier,
startDestination: String = FOR_YOU_ROUTE,
) {
val navController = appState.navController
NavHost(
navController = navController,
startDestination = startDestination,
startDestination = ForYouRoute,
modifier = modifier,
) {
forYouScreen(onTopicClick = navController::navigateToInterests)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@

package com.google.samples.apps.nowinandroid.navigation

import androidx.annotation.StringRes
import androidx.compose.ui.graphics.vector.ImageVector
import com.google.samples.apps.nowinandroid.R
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.feature.bookmarks.navigation.BookmarksRoute
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.ForYouRoute
import com.google.samples.apps.nowinandroid.feature.interests.navigation.InterestsRoute
import kotlin.reflect.KClass
import com.google.samples.apps.nowinandroid.feature.bookmarks.R as bookmarksR
import com.google.samples.apps.nowinandroid.feature.foryou.R as forYouR
import com.google.samples.apps.nowinandroid.feature.search.R as searchR
Expand All @@ -31,25 +36,29 @@ import com.google.samples.apps.nowinandroid.feature.search.R as searchR
enum class TopLevelDestination(
val selectedIcon: ImageVector,
val unselectedIcon: ImageVector,
val iconTextId: Int,
val titleTextId: Int,
@StringRes val iconTextId: Int,
@StringRes val titleTextId: Int,
val route: KClass<*>,
) {
FOR_YOU(
selectedIcon = NiaIcons.Upcoming,
unselectedIcon = NiaIcons.UpcomingBorder,
iconTextId = forYouR.string.feature_foryou_title,
titleTextId = R.string.app_name,
route = ForYouRoute::class,
),
BOOKMARKS(
selectedIcon = NiaIcons.Bookmarks,
unselectedIcon = NiaIcons.BookmarksBorder,
iconTextId = bookmarksR.string.feature_bookmarks_title,
titleTextId = bookmarksR.string.feature_bookmarks_title,
route = BookmarksRoute::class,
),
INTERESTS(
selectedIcon = NiaIcons.Grid3x3,
unselectedIcon = NiaIcons.Grid3x3,
iconTextId = searchR.string.feature_search_interests,
titleTextId = searchR.string.feature_search_interests,
route = InterestsRoute::class,
),
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hasRoute
import androidx.navigation.NavDestination.Companion.hierarchy
import com.google.samples.apps.nowinandroid.R
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaBackground
Expand All @@ -72,6 +73,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.theme.LocalGradien
import com.google.samples.apps.nowinandroid.feature.settings.SettingsDialog
import com.google.samples.apps.nowinandroid.navigation.NiaNavHost
import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination
import kotlin.reflect.KClass
import com.google.samples.apps.nowinandroid.feature.settings.R as settingsR

@OptIn(ExperimentalMaterial3AdaptiveApi::class)
Expand Down Expand Up @@ -150,7 +152,7 @@ internal fun NiaApp(
appState.topLevelDestinations.forEach { destination ->
val hasUnread = unreadDestinations.contains(destination)
val selected = currentDestination
.isTopLevelDestinationInHierarchy(destination)
.isRouteInHierarchy(destination.route)
item(
selected = selected,
onClick = { appState.navigateToTopLevelDestination(destination) },
Expand Down Expand Up @@ -198,8 +200,10 @@ internal fun NiaApp(
) {
// Show the top app bar on top level destinations.
val destination = appState.currentTopLevelDestination
val shouldShowTopAppBar = destination != null
var shouldShowTopAppBar = false

if (destination != null) {
shouldShowTopAppBar = true
NiaTopAppBar(
titleRes = destination.titleTextId,
navigationIcon = NiaIcons.Search,
Expand Down Expand Up @@ -266,7 +270,7 @@ private fun Modifier.notificationDot(): Modifier =
}
}

private fun NavDestination?.isTopLevelDestinationInHierarchy(destination: TopLevelDestination) =
private fun NavDestination?.isRouteInHierarchy(route: KClass<*>) =
this?.hierarchy?.any {
it.route?.contains(destination.name, true) ?: false
it.hasRoute(route)
} ?: false
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.navigation.NavController
import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hasRoute
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
Expand All @@ -32,11 +33,8 @@ import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourc
import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor
import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor
import com.google.samples.apps.nowinandroid.core.ui.TrackDisposableJank
import com.google.samples.apps.nowinandroid.feature.bookmarks.navigation.BOOKMARKS_ROUTE
import com.google.samples.apps.nowinandroid.feature.bookmarks.navigation.navigateToBookmarks
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.FOR_YOU_ROUTE
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.navigateToForYou
import com.google.samples.apps.nowinandroid.feature.interests.navigation.INTERESTS_ROUTE
import com.google.samples.apps.nowinandroid.feature.interests.navigation.navigateToInterests
import com.google.samples.apps.nowinandroid.feature.search.navigation.navigateToSearch
import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination
Expand Down Expand Up @@ -90,11 +88,10 @@ class NiaAppState(
.currentBackStackEntryAsState().value?.destination

val currentTopLevelDestination: TopLevelDestination?
@Composable get() = when (currentDestination?.route) {
FOR_YOU_ROUTE -> FOR_YOU
BOOKMARKS_ROUTE -> BOOKMARKS
INTERESTS_ROUTE -> INTERESTS
else -> null
@Composable get() {
return TopLevelDestination.entries.firstOrNull { topLevelDestination ->
currentDestination?.hasRoute(route = topLevelDestination.route) ?: false
}
}

val isOffline = networkMonitor.isOnline
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,26 @@ package com.google.samples.apps.nowinandroid.ui.interests2pane

import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import com.google.samples.apps.nowinandroid.feature.interests.navigation.TOPIC_ID_ARG
import androidx.navigation.toRoute
import com.google.samples.apps.nowinandroid.feature.interests.navigation.InterestsRoute
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject

const val TOPIC_ID_KEY = "selectedTopicId"

@HiltViewModel
class Interests2PaneViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle,
) : ViewModel() {
val selectedTopicId: StateFlow<String?> =
savedStateHandle.getStateFlow(TOPIC_ID_ARG, savedStateHandle[TOPIC_ID_ARG])

val route = savedStateHandle.toRoute<InterestsRoute>()
val selectedTopicId: StateFlow<String?> = savedStateHandle.getStateFlow(
key = TOPIC_ID_KEY,
initialValue = route.initialTopicId,
)

fun onTopicClick(topicId: String?) {
savedStateHandle[TOPIC_ID_ARG] = topicId
savedStateHandle[TOPIC_ID_KEY] = topicId
}
}
Loading