Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 9 additions & 4 deletions app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ config:
graph TB
subgraph :feature
direction TB
subgraph :feature:settings
direction TB
:feature:settings:impl[impl]:::android-library
end
subgraph :feature:foryou
direction TB
:feature:foryou:api[api]:::android-library
Expand All @@ -32,6 +28,11 @@ graph TB
:feature:search:api[api]:::android-library
:feature:search:impl[impl]:::android-library
end
subgraph :feature:settings
direction TB
:feature:settings:api[api]:::android-library
:feature:settings:impl[impl]:::android-library
end
subgraph :feature:interests
direction TB
:feature:interests:api[api]:::android-library
Expand Down Expand Up @@ -81,6 +82,7 @@ graph TB
:app -.-> :feature:interests:impl
:app -.-> :feature:search:api
:app -.-> :feature:search:impl
:app -.-> :feature:settings:api
:app -.-> :feature:settings:impl
:app -.-> :feature:topic:api
:app -.-> :feature:topic:impl
Expand Down Expand Up @@ -128,13 +130,16 @@ graph TB
:feature:search:api --> :core:navigation
:feature:search:impl -.-> :core:designsystem
:feature:search:impl -.-> :core:domain
:feature:search:impl -.-> :core:navigation
:feature:search:impl -.-> :core:ui
:feature:search:impl -.-> :feature:interests:api
:feature:search:impl -.-> :feature:search:api
:feature:search:impl -.-> :feature:topic:api
:feature:settings:api --> :core:navigation
:feature:settings:impl -.-> :core:data
:feature:settings:impl -.-> :core:designsystem
:feature:settings:impl -.-> :core:ui
:feature:settings:impl -.-> :feature:settings:api
:feature:topic:api -.-> :core:designsystem
:feature:topic:api --> :core:navigation
:feature:topic:api -.-> :core:ui
Expand Down
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ dependencies {
implementation(projects.feature.topic.impl)
implementation(projects.feature.search.api)
implementation(projects.feature.search.impl)
implementation(projects.feature.settings.api)
implementation(projects.feature.settings.impl)

implementation(projects.core.common)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
Expand All @@ -63,6 +60,7 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation3.runtime.NavKey
import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.scene.DialogSceneStrategy
import androidx.navigation3.ui.NavDisplay
import com.google.samples.apps.nowinandroid.R
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaBackground
Expand All @@ -81,7 +79,8 @@ import com.google.samples.apps.nowinandroid.feature.foryou.impl.navigation.forYo
import com.google.samples.apps.nowinandroid.feature.interests.impl.navigation.interestsEntry
import com.google.samples.apps.nowinandroid.feature.search.api.navigation.SearchNavKey
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.settings.api.navigation.SettingsNavKey
import com.google.samples.apps.nowinandroid.feature.settings.impl.navigation.settingsEntry
import com.google.samples.apps.nowinandroid.feature.topic.impl.navigation.topicEntry
import com.google.samples.apps.nowinandroid.navigation.TOP_LEVEL_NAV_ITEMS
import com.google.samples.apps.nowinandroid.feature.settings.impl.R as settingsR
Expand All @@ -93,7 +92,6 @@ fun NiaApp(
windowAdaptiveInfo: WindowAdaptiveInfo = currentWindowAdaptiveInfo(),
) {
val shouldShowGradientBackground = appState.navigationState.currentTopLevelKey == ForYouNavKey
var showSettingsDialog by rememberSaveable { mutableStateOf(false) }

NiaBackground(modifier = modifier) {
NiaGradientBackground(
Expand All @@ -118,13 +116,8 @@ fun NiaApp(
}
}
CompositionLocalProvider(LocalSnackbarHostState provides snackbarHostState) {
NiaApp(
NiaAppContent(
appState = appState,

// TODO: Settings should be a dialog screen
showSettingsDialog = showSettingsDialog,
onSettingsDismissed = { showSettingsDialog = false },
onTopAppBarActionClick = { showSettingsDialog = true },
windowAdaptiveInfo = windowAdaptiveInfo,
)
}
Expand All @@ -138,23 +131,14 @@ fun NiaApp(
ExperimentalComposeUiApi::class,
ExperimentalMaterial3AdaptiveApi::class,
)
internal fun NiaApp(
internal fun NiaAppContent(
appState: NiaAppState,
showSettingsDialog: Boolean,
onSettingsDismissed: () -> Unit,
onTopAppBarActionClick: () -> Unit,
modifier: Modifier = Modifier,
windowAdaptiveInfo: WindowAdaptiveInfo = currentWindowAdaptiveInfo(),
) {
val unreadNavKeys by appState.topLevelNavKeysWithUnreadResources
.collectAsStateWithLifecycle()

if (showSettingsDialog) {
SettingsDialog(
onDismiss = { onSettingsDismissed() },
)
}

val snackbarHostState = LocalSnackbarHostState.current

val navigator = remember { Navigator(appState.navigationState) }
Expand Down Expand Up @@ -220,7 +204,7 @@ internal fun NiaApp(
// Only show the top app bar on top level destinations.
var shouldShowTopAppBar = false

if (appState.navigationState.currentKey in appState.navigationState.topLevelKeys) {
if (appState.navigationState.currentKeyIgnoringDialogs in appState.navigationState.topLevelKeys) {
shouldShowTopAppBar = true

val destination = TOP_LEVEL_NAV_ITEMS[appState.navigationState.currentTopLevelKey]
Expand All @@ -239,7 +223,7 @@ internal fun NiaApp(
colors = TopAppBarDefaults.topAppBarColors(
containerColor = Color.Transparent,
),
onActionClick = { onTopAppBarActionClick() },
onActionClick = { navigator.navigate(SettingsNavKey) },
onNavigationClick = { navigator.navigate(SearchNavKey) },
)
}
Expand All @@ -255,18 +239,20 @@ internal fun NiaApp(
),
) {
val listDetailStrategy = rememberListDetailSceneStrategy<NavKey>()
val dialogStrategy = remember { DialogSceneStrategy<NavKey>() }

val entryProvider = entryProvider {
forYouEntry(navigator)
bookmarksEntry(navigator)
interestsEntry(navigator)
topicEntry(navigator)
searchEntry(navigator)
settingsEntry(navigator)
}

NavDisplay(
entries = appState.navigationState.toEntries(entryProvider),
sceneStrategy = listDetailStrategy,
sceneStrategy = dialogStrategy then listDetailStrategy,
onBack = { navigator.goBack() },
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,8 @@ class SnackbarInsetsScreenshotTests {
userNewsResourceRepository = userNewsResourceRepository,
timeZoneMonitor = timeZoneMonitor,
)
NiaApp(
NiaAppContent(
appState = appState,
showSettingsDialog = false,
onSettingsDismissed = {},
onTopAppBarActionClick = {},
windowAdaptiveInfo = WindowAdaptiveInfo(
windowSizeClass = WindowSizeClass.compute(
maxWidth.value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,8 @@ class SnackbarScreenshotTests {
userNewsResourceRepository = userNewsResourceRepository,
timeZoneMonitor = timeZoneMonitor,
)
NiaApp(
NiaAppContent(
appState = appState,
showSettingsDialog = false,
onSettingsDismissed = {},
onTopAppBarActionClick = {},
windowAdaptiveInfo = WindowAdaptiveInfo(
windowSizeClass = WindowSizeClass.compute(
maxWidth.value,
Expand Down
13 changes: 9 additions & 4 deletions benchmarks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ config:
graph TB
subgraph :feature
direction TB
subgraph :feature:settings
direction TB
:feature:settings:impl[impl]:::android-library
end
subgraph :feature:foryou
direction TB
:feature:foryou:api[api]:::android-library
Expand All @@ -32,6 +28,11 @@ graph TB
:feature:search:api[api]:::android-library
:feature:search:impl[impl]:::android-library
end
subgraph :feature:settings
direction TB
:feature:settings:api[api]:::android-library
:feature:settings:impl[impl]:::android-library
end
subgraph :feature:interests
direction TB
:feature:interests:api[api]:::android-library
Expand Down Expand Up @@ -81,6 +82,7 @@ graph TB
:app -.-> :feature:interests:impl
:app -.-> :feature:search:api
:app -.-> :feature:search:impl
:app -.-> :feature:settings:api
:app -.-> :feature:settings:impl
:app -.-> :feature:topic:api
:app -.-> :feature:topic:impl
Expand Down Expand Up @@ -128,13 +130,16 @@ graph TB
:feature:search:api --> :core:navigation
:feature:search:impl -.-> :core:designsystem
:feature:search:impl -.-> :core:domain
:feature:search:impl -.-> :core:navigation
:feature:search:impl -.-> :core:ui
:feature:search:impl -.-> :feature:interests:api
:feature:search:impl -.-> :feature:search:api
:feature:search:impl -.-> :feature:topic:api
:feature:settings:api --> :core:navigation
:feature:settings:impl -.-> :core:data
:feature:settings:impl -.-> :core:designsystem
:feature:settings:impl -.-> :core:ui
:feature:settings:impl -.-> :feature:settings:api
:feature:topic:api -.-> :core:designsystem
:feature:topic:api --> :core:navigation
:feature:topic:api -.-> :core:ui
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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.navigation

import androidx.navigation3.runtime.NavKey

/**
* [NavKey] that must behave as a dialog when handled by a [DialogSceneStrategy].
*/
interface DialogNavKey : NavKey
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ class NavigationState(

@get:VisibleForTesting
val currentKey: NavKey by derivedStateOf { currentSubStack.last() }

/**
* Current [NavKey] but ignores [DialogNavKey]s that could be added on top.
*/
val currentKeyIgnoringDialogs: NavKey by derivedStateOf { currentSubStack.last { it !is DialogNavKey } }
Comment on lines +79 to +82
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dturner I'm open to suggestions on how to properly support this.

}

/**
Expand Down
1 change: 1 addition & 0 deletions feature/search/impl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ graph TB
:feature:search:api --> :core:navigation
:feature:search:impl -.-> :core:designsystem
:feature:search:impl -.-> :core:domain
:feature:search:impl -.-> :core:navigation
:feature:search:impl -.-> :core:ui
:feature:search:impl -.-> :feature:interests:api
:feature:search:impl -.-> :feature:search:api
Expand Down
1 change: 1 addition & 0 deletions feature/search/impl/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ android {

dependencies {
implementation(projects.core.domain)
implementation(projects.core.navigation)
implementation(projects.feature.interests.api)
implementation(projects.feature.search.api)
implementation(projects.feature.topic.api)
Expand Down
57 changes: 57 additions & 0 deletions feature/settings/api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# `:feature:settings:api`

## Module dependency graph

<!--region graph-->
```mermaid
---
config:
layout: elk
elk:
nodePlacementStrategy: SIMPLE
---
graph TB
subgraph :feature
direction TB
subgraph :feature:settings
direction TB
:feature:settings:api[api]:::android-library
end
end
subgraph :core
direction TB
:core:navigation[navigation]:::android-library
end

:feature:settings:api --> :core:navigation

classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;
```

<details><summary>📋 Graph legend</summary>

```mermaid
graph TB
application[application]:::android-application
feature[feature]:::android-feature
library[library]:::android-library
jvm[jvm]:::jvm-library

application -.-> feature
library --> jvm

classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;
```

</details>
<!--endregion-->
23 changes: 23 additions & 0 deletions feature/settings/api/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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.
*/

plugins {
alias(libs.plugins.nowinandroid.android.feature.api)
}

android {
namespace = "com.google.samples.apps.nowinandroid.feature.settings.api"
}
Loading
Loading