Add material 3 adaptive dependencies and fix compilation errors

pull/2064/head
lihenggui 1 year ago
parent 539d36fb0b
commit 528ee11110

@ -92,6 +92,8 @@ kotlin {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material)
implementation(compose.material3)
implementation(compose.material3AdaptiveNavigationSuite)
implementation(compose.ui)
implementation(compose.components.resources)
implementation(compose.components.uiToolingPreview)
@ -100,6 +102,7 @@ kotlin {
implementation(libs.coil.core)
implementation(libs.coil.compose)
implementation(libs.kotlinx.serialization.json)
implementation(libs.jetbrains.compose.material3.adaptive.navigation)
}
androidMain.dependencies {

@ -60,8 +60,8 @@ class NavigationTest {
/**
* Manages the components' state and is used to perform injection on your test
*/
@get:Rule(order = 0)
val hiltRule = HiltAndroidRule(this)
// @get:Rule(order = 0)
// val hiltRule = HiltAndroidRule(this)
/**
* Grant [android.Manifest.permission.POST_NOTIFICATIONS] permission.
@ -89,8 +89,8 @@ class NavigationTest {
private val brand by composeTestRule.stringResource(SettingsR.string.feature_settings_brand_android)
private val ok by composeTestRule.stringResource(SettingsR.string.feature_settings_dismiss_dialog_button_text)
@Before
fun setup() = hiltRule.inject()
// @Before
// fun setup() = hiltRule.inject()
@Test
fun firstScreen_isForYou() {

@ -19,15 +19,6 @@
<uses-permission android:name="android.permission.INTERNET" />
<!--
Firebase automatically adds these AD_ID and ADSERVICES permissions, even though we don't use them.
If you use these permissions you must declare how you're using them to Google Play, otherwise the
app will be rejected when publishing it. To avoid this we remove the permissions entirely.
-->
<uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove"/>
<uses-permission android:name="android.permission.ACCESS_ADSERVICES_ATTRIBUTION" tools:node="remove"/>
<uses-permission android:name="android.permission.ACCESS_ADSERVICES_AD_ID" tools:node="remove"/>
<application
android:name=".NiaApplication"
android:allowBackup="true"

@ -51,6 +51,7 @@ import com.google.samples.apps.nowinandroid.ui.rememberNiaAppState
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import org.koin.core.context.GlobalContext.get
class MainActivity : ComponentActivity() {
@ -58,26 +59,18 @@ class MainActivity : ComponentActivity() {
/**
* Lazily inject [JankStats], which is used to track jank throughout the app.
*/
private val lazyStats: JankStats = get()
private val stats: JankStats by inject()
@Inject
lateinit var networkMonitor: NetworkMonitor
private val networkMonitor: NetworkMonitor by inject()
@Inject
lateinit var timeZoneMonitor: TimeZoneMonitor
private val timeZoneMonitor: TimeZoneMonitor by inject()
@Inject
lateinit var analyticsHelper: AnalyticsHelper
private val analyticsHelper: AnalyticsHelper by inject()
@Inject
lateinit var userNewsResourceRepository: UserNewsResourceRepository
private val userNewsResourceRepository: UserNewsResourceRepository by inject()
private val viewModel: MainActivityViewModel by viewModels()
override val component by lazy(LazyThreadSafetyMode.NONE) {
ApplicationComponent::class.create(applicationContext)
}
override fun onCreate(savedInstanceState: Bundle?) {
val splashScreen = installSplashScreen()
super.onCreate(savedInstanceState)
@ -154,12 +147,12 @@ class MainActivity : ComponentActivity() {
override fun onResume() {
super.onResume()
lazyStats.get().isTrackingEnabled = true
stats.isTrackingEnabled = true
}
override fun onPause() {
super.onPause()
lazyStats.get().isTrackingEnabled = false
stats.isTrackingEnabled = false
}
}

@ -26,7 +26,9 @@ import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import org.koin.android.annotation.KoinViewModel
@KoinViewModel
class MainActivityViewModel(
userDataRepository: UserDataRepository,
) : ViewModel() {

@ -21,14 +21,11 @@ import coil3.ImageLoader
import coil3.PlatformContext
import coil3.SingletonImageLoader
import coil3.request.crossfade
import com.google.samples.apps.nowinandroid.core.analytics.di.analyticsModule
import com.google.samples.apps.nowinandroid.core.di.CommonModule
import com.google.samples.apps.nowinandroid.core.di.commonModule
import com.google.samples.apps.nowinandroid.di.appModules
import com.google.samples.apps.nowinandroid.util.ProfileVerifierLogger
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.startKoin
import org.koin.ksp.generated.module
/**
* [Application] class for NiA
@ -42,18 +39,14 @@ class NiaApplication : Application(), SingletonImageLoader.Factory {
startKoin {
androidLogger()
androidContext(this@NiaApplication)
val allModules =
modules(
CommonModule().module,
AnalyticModule().module,
)
modules(appModules)
}
// Initialize Sync; the system responsible for keeping data in the app up to date.
// Sync.initialize(context = this)
profileVerifierLogger()
}
override fun newImageLoader(context: PlatformContext): ImageLoader{
override fun newImageLoader(context: PlatformContext): ImageLoader {
return ImageLoader.Builder(context)
.crossfade(true)
.build()

@ -0,0 +1,62 @@
/*
* Copyright 2024 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.di
import com.google.samples.apps.nowinandroid.core.analytics.di.AnalyticsModule
import com.google.samples.apps.nowinandroid.core.data.di.dataModule
import com.google.samples.apps.nowinandroid.core.database.di.databaseModule
import com.google.samples.apps.nowinandroid.core.datastore.di.dataStoreModule
import com.google.samples.apps.nowinandroid.core.di.commonModule
import com.google.samples.apps.nowinandroid.core.network.di.networkModule
import com.google.samples.apps.nowinandroid.feature.bookmarks.di.bookmarksModule
import com.google.samples.apps.nowinandroid.feature.foryou.di.forYouModule
import com.google.samples.apps.nowinandroid.feature.interests.di.interestModule
import com.google.samples.apps.nowinandroid.feature.search.di.searchModule
import com.google.samples.apps.nowinandroid.feature.settings.di.settingsModule
import com.google.samples.apps.nowinandroid.feature.topic.di.topicModule
import org.koin.core.annotation.ComponentScan
import org.koin.core.annotation.Module
import org.koin.dsl.module
import org.koin.ksp.generated.module
@Module
@ComponentScan
class AppModule
val featureModules = module {
includes(
forYouModule,
interestModule,
topicModule,
bookmarksModule,
searchModule,
settingsModule,
)
}
val appModules = module {
includes(
*commonModule().toTypedArray(),
AnalyticsModule().module,
*databaseModule().toTypedArray(),
*dataModule().toTypedArray(),
dataStoreModule(),
*networkModule().toTypedArray(),
)
includes(featureModules)
includes(JankStatsModule().module, AppModule().module)
}

@ -23,6 +23,7 @@ import com.google.samples.apps.nowinandroid.feature.bookmarks.navigation.Bookmar
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.ForYouRoute
import com.google.samples.apps.nowinandroid.feature.interests.navigation.InterestsRoute
import nowinandroid.app.generated.resources.Res
import nowinandroid.app.generated.resources.app_name
import nowinandroid.feature.bookmarks.generated.resources.feature_bookmarks_title
import nowinandroid.feature.foryou.generated.resources.feature_foryou_title
import nowinandroid.feature.search.generated.resources.feature_search_interests

@ -37,7 +37,6 @@ import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.SnackbarResult.ActionPerformed
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
import androidx.compose.material3.adaptive.WindowAdaptiveInfo
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.runtime.Composable
@ -54,7 +53,6 @@ import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.unit.dp
@ -62,7 +60,6 @@ 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
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaGradientBackground
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationSuiteScaffold
@ -73,10 +70,14 @@ 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 nowinandroid.app.generated.resources.Res
import nowinandroid.app.generated.resources.not_connected
import nowinandroid.feature.settings.generated.resources.feature_settings_top_app_bar_action_icon_description
import nowinandroid.feature.settings.generated.resources.feature_settings_top_app_bar_navigation_icon_description
import kotlin.reflect.KClass
import com.google.samples.apps.nowinandroid.feature.settings.R as settingsR
import nowinandroid.feature.settings.generated.resources.Res as settingsR
import org.jetbrains.compose.resources.stringResource
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
fun NiaApp(
appState: NiaAppState,
@ -100,7 +101,7 @@ fun NiaApp(
val isOffline by appState.isOffline.collectAsStateWithLifecycle()
// If user is not connected to the internet show a snack bar to inform them.
val notConnectedMessage = stringResource(R.string.not_connected)
val notConnectedMessage = stringResource(Res.string.not_connected)
LaunchedEffect(isOffline) {
if (isOffline) {
snackbarHostState.showSnackbar(
@ -126,7 +127,6 @@ fun NiaApp(
@OptIn(
ExperimentalMaterial3Api::class,
ExperimentalComposeUiApi::class,
ExperimentalMaterial3AdaptiveApi::class,
)
internal fun NiaApp(
appState: NiaAppState,
@ -205,14 +205,14 @@ internal fun NiaApp(
if (destination != null) {
shouldShowTopAppBar = true
NiaTopAppBar(
titleRes = destination.titleTextId,
title = stringResource(destination.titleTextId),
navigationIcon = NiaIcons.Search,
navigationIconContentDescription = stringResource(
id = settingsR.string.feature_settings_top_app_bar_navigation_icon_description,
resource = settingsR.string.feature_settings_top_app_bar_navigation_icon_description,
),
actionIcon = NiaIcons.Settings,
actionIconContentDescription = stringResource(
id = settingsR.string.feature_settings_top_app_bar_action_icon_description,
resource = settingsR.string.feature_settings_top_app_bar_action_icon_description,
),
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
containerColor = Color.Transparent,

@ -22,6 +22,7 @@ import com.google.samples.apps.nowinandroid.core.di.ApplicationScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.guava.await
import kotlinx.coroutines.launch
import org.koin.core.annotation.Single
/**
* Logs the app's Baseline Profile Compilation Status using [ProfileVerifier].
@ -47,6 +48,7 @@ import kotlinx.coroutines.launch
*
* @see androidx.profileinstaller.ProfileVerifier.CompilationStatus.ResultCode
*/
@Single
class ProfileVerifierLogger(
@ApplicationScope private val scope: CoroutineScope,
) {

@ -47,6 +47,7 @@ class CmpFeatureConventionPlugin : Plugin<Project> {
add("commonMainImplementation", project(":core:designsystem"))
add("commonMainImplementation", libs.findLibrary("jetbrains.compose.viewmodel").get())
add("commonMainImplementation", libs.findLibrary("jetbrains.compose.navigation").get())
"commonMainImplementation"(platform(libs.findLibrary("koin.bom").get()))
add("commonMainImplementation", libs.findLibrary("koin.compose").get())
add("commonMainImplementation", libs.findLibrary("koin.compose.viewmodel").get())
add("commonMainImplementation", libs.findLibrary("koin.compose.viewmodel.navigation").get())

@ -16,10 +16,14 @@
package com.google.samples.apps.nowinandroid.core.analytics.di
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper
import com.google.samples.apps.nowinandroid.core.analytics.StubAnalyticsHelper
import org.koin.core.module.dsl.singleOf
import org.koin.dsl.module
import org.koin.core.annotation.Module
import org.koin.core.annotation.Single
val analyticsModule = module {
singleOf(::StubAnalyticsHelper)
@Module
class AnalyticsModule {
@Single
fun providesAnalyticsHelper(): AnalyticsHelper = StubAnalyticsHelper()
}

@ -24,15 +24,17 @@ import com.google.samples.apps.nowinandroid.core.data.repository.OfflineFirstTop
import com.google.samples.apps.nowinandroid.core.data.repository.OfflineFirstUserDataRepository
import org.koin.core.annotation.ComponentScan
import org.koin.core.annotation.Module
import org.koin.core.module.dsl.singleOf
import org.koin.core.qualifier.named
import org.koin.dsl.module
import org.koin.ksp.generated.module
internal val repositoryModule = module {
single { OfflineFirstTopicsRepository(get(), get()) }
single { OfflineFirstNewsRepository(get(), get(), get(), get(), get()) }
single { OfflineFirstUserDataRepository(get(), get()) }
single { DefaultRecentSearchRepository(get()) }
singleOf(::OfflineFirstTopicsRepository)
singleOf(::OfflineFirstNewsRepository)
singleOf(::OfflineFirstUserDataRepository)
singleOf(::DefaultRecentSearchRepository)
singleOf(::CompositeUserNewsResourceRepository)
single {
DefaultSearchContentsRepository(
get(),
@ -42,7 +44,6 @@ internal val repositoryModule = module {
get(named("IoDispatcher")),
)
}
single { CompositeUserNewsResourceRepository(get(), get()) }
}
internal val networkMonitorModule = module {
@ -59,7 +60,7 @@ internal val timeZoneMonitorProviderModule = module {
}
}
val dataModule = listOf(
fun dataModule() = listOf(
DataModule().module,
repositoryModule,
networkMonitorModule,

@ -60,7 +60,8 @@ internal val daoModule = module {
}
}
val databaseModule = listOf(
fun databaseModule() = listOf(
driverModule,
DatabaseModule().module,
daoModule,
)

@ -21,7 +21,7 @@ import com.russhwolf.settings.Settings
import org.koin.core.qualifier.named
import org.koin.dsl.module
val settingsModule = module {
fun dataStoreModule() = module {
single { Settings() }
single {
NiaPreferencesDataSource(

@ -72,16 +72,19 @@ kotlin {
implementation(projects.core.testing)
}
commonMain.dependencies {
implementation(libs.coil.compose)
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material)
implementation(compose.material3)
implementation(compose.material3AdaptiveNavigationSuite)
implementation(compose.materialIconsExtended)
implementation(compose.ui)
implementation(compose.uiUtil)
implementation(compose.components.resources)
implementation(compose.components.uiToolingPreview)
implementation(libs.coil.compose)
implementation(libs.jetbrains.compose.material3.adaptive)
implementation(libs.jetbrains.compose.material3.adaptive.layout)
}
}
}

@ -23,10 +23,20 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.NavigationBarItemDefaults
import androidx.compose.material3.NavigationDrawerItemDefaults
import androidx.compose.material3.NavigationRail
import androidx.compose.material3.NavigationRailItem
import androidx.compose.material3.NavigationRailItemDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
import androidx.compose.material3.adaptive.WindowAdaptiveInfo
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.material3.adaptive.navigationsuite.ExperimentalMaterial3AdaptiveNavigationSuiteApi
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteDefaults
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteItemColors
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffold
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffoldDefaults
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScope
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@ -165,6 +175,96 @@ fun NiaNavigationRail(
)
}
/**
* Now in Android navigation suite scaffold with item and content slots.
* Wraps Material 3 [NavigationSuiteScaffold].
*
* @param modifier Modifier to be applied to the navigation suite scaffold.
* @param navigationSuiteItems A slot to display multiple items via [NiaNavigationSuiteScope].
* @param windowAdaptiveInfo The window adaptive info.
* @param content The app content inside the scaffold.
*/
@Composable
fun NiaNavigationSuiteScaffold(
navigationSuiteItems: NiaNavigationSuiteScope.() -> Unit,
modifier: Modifier = Modifier,
windowAdaptiveInfo: WindowAdaptiveInfo = currentWindowAdaptiveInfo(),
content: @Composable () -> Unit,
) {
val layoutType = NavigationSuiteScaffoldDefaults
.calculateFromAdaptiveInfo(windowAdaptiveInfo)
val navigationSuiteItemColors = NavigationSuiteItemColors(
navigationBarItemColors = NavigationBarItemDefaults.colors(
selectedIconColor = NiaNavigationDefaults.navigationSelectedItemColor(),
unselectedIconColor = NiaNavigationDefaults.navigationContentColor(),
selectedTextColor = NiaNavigationDefaults.navigationSelectedItemColor(),
unselectedTextColor = NiaNavigationDefaults.navigationContentColor(),
indicatorColor = NiaNavigationDefaults.navigationIndicatorColor(),
),
navigationRailItemColors = NavigationRailItemDefaults.colors(
selectedIconColor = NiaNavigationDefaults.navigationSelectedItemColor(),
unselectedIconColor = NiaNavigationDefaults.navigationContentColor(),
selectedTextColor = NiaNavigationDefaults.navigationSelectedItemColor(),
unselectedTextColor = NiaNavigationDefaults.navigationContentColor(),
indicatorColor = NiaNavigationDefaults.navigationIndicatorColor(),
),
navigationDrawerItemColors = NavigationDrawerItemDefaults.colors(
selectedIconColor = NiaNavigationDefaults.navigationSelectedItemColor(),
unselectedIconColor = NiaNavigationDefaults.navigationContentColor(),
selectedTextColor = NiaNavigationDefaults.navigationSelectedItemColor(),
unselectedTextColor = NiaNavigationDefaults.navigationContentColor(),
),
)
NavigationSuiteScaffold(
navigationSuiteItems = {
NiaNavigationSuiteScope(
navigationSuiteScope = this,
navigationSuiteItemColors = navigationSuiteItemColors,
).run(navigationSuiteItems)
},
layoutType = layoutType,
containerColor = Color.Transparent,
navigationSuiteColors = NavigationSuiteDefaults.colors(
navigationBarContentColor = NiaNavigationDefaults.navigationContentColor(),
navigationRailContainerColor = Color.Transparent,
),
modifier = modifier,
) {
content()
}
}
/**
* A wrapper around [NavigationSuiteScope] to declare navigation items.
*/
class NiaNavigationSuiteScope internal constructor(
private val navigationSuiteScope: NavigationSuiteScope,
private val navigationSuiteItemColors: NavigationSuiteItemColors,
) {
fun item(
selected: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier,
icon: @Composable () -> Unit,
selectedIcon: @Composable () -> Unit = icon,
label: @Composable (() -> Unit)? = null,
) = navigationSuiteScope.item(
selected = selected,
onClick = onClick,
icon = {
if (selected) {
selectedIcon()
} else {
icon()
}
},
label = label,
colors = navigationSuiteItemColors,
modifier = modifier,
)
}
@ThemePreviews
@Composable
fun NiaNavigationBarPreview() {

@ -18,11 +18,6 @@ package com.google.samples.apps.nowinandroid.core.domain.di
import org.koin.core.annotation.ComponentScan
import org.koin.core.annotation.Module
import org.koin.ksp.generated.module
val domainModule = listOf(
DomainModule().module,
)
@Module
@ComponentScan

@ -60,7 +60,7 @@ internal val ktorfitModule = module {
singleOf(::RetrofitNiaNetwork)
}
val networkModule = listOf(NetworkModule().module, jsonModule, ktorfitModule)
fun networkModule() = listOf(NetworkModule().module, jsonModule, ktorfitModule)
@Module
@ComponentScan

@ -19,7 +19,7 @@ package com.google.samples.apps.nowinandroid.core.notifications.di
import com.google.samples.apps.nowinandroid.core.notifications.NoOpNotifier
import org.koin.dsl.module
val notificationModule = module {
fun notificationModule() = module {
// TODO replace with a real implementation
single { NoOpNotifier() }
}

@ -0,0 +1,27 @@
/*
* Copyright 2024 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.feature.bookmarks.di
import com.google.samples.apps.nowinandroid.feature.bookmarks.BookmarksViewModel
import org.koin.core.module.dsl.viewModel
import org.koin.core.module.dsl.viewModelOf
import org.koin.dsl.module
val bookmarksModule = module {
viewModel { BookmarksViewModel(get(), get()) }
}

@ -20,7 +20,7 @@ import com.google.samples.apps.nowinandroid.feature.settings.SettingsViewModel
import org.koin.core.module.dsl.viewModel
import org.koin.dsl.module
val settingModule = module {
val settingsModule = module {
viewModel {
SettingsViewModel(get())
}

@ -4,20 +4,20 @@ androidDesugarJdkLibs = "2.1.2"
# AGP and tools should be updated together
androidGradlePlugin = "8.7.1"
androidTools = "31.7.1"
androidxActivity = "1.9.2"
androidxActivity = "1.9.3"
androidxAppCompat = "1.7.0"
androidxBrowser = "1.8.0"
androidxComposeBom = "2024.09.03"
androidxComposeRuntimeTracing = "1.7.3"
androidxComposeBom = "2024.10.00"
androidxComposeRuntimeTracing = "1.7.4"
androidxCore = "1.13.1"
androidxCoreSplashscreen = "1.0.1"
androidxDataStore = "1.1.1"
androidxEspresso = "3.6.1"
androidxHiltNavigationCompose = "1.2.0"
androidxLifecycle = "2.8.6"
androidxMacroBenchmark = "1.3.2"
androidxMacroBenchmark = "1.3.3"
androidxMetrics = "1.0.0-beta01"
androidxNavigation = "2.8.2"
androidxNavigation = "2.8.3"
androidxProfileinstaller = "1.4.1"
androidxTestCore = "1.6.1"
androidxTestExt = "1.2.1"
@ -44,6 +44,7 @@ kotlinxCoroutines = "1.9.0"
kotlinxDatetime = "0.6.1"
kotlinxSerializationJson = "1.7.3"
ksp = "2.0.21-1.0.25"
material3adaptive = "1.0.0-alpha03"
moduleGraph = "2.7.1"
okhttp = "4.12.0"
protobuf = "4.28.2"
@ -60,8 +61,8 @@ androidx-constraintlayout = "2.1.4"
androidx-espresso-core = "3.6.1"
androidx-material = "1.12.0"
androidx-test-junit = "1.2.1"
compose-ui-tooling = "1.7.3"
compose-plugin = "1.7.0-rc01"
compose-ui-tooling = "1.7.4"
compose-plugin = "1.7.0"
sqldelight = "2.0.2"
kotlinInject = '0.7.2'
multiplatform-settings = "1.2.0"
@ -222,6 +223,9 @@ ktorfit-converters-call = { group = "de.jensklingenberg.ktorfit", name = "ktorfi
buildkonfig-gradlePlugin = { group = "com.codingfeline.buildkonfig", name = "buildkonfig-gradle-plugin", version.ref = "buildKonfig" }
jetbrains-compose-viewmodel = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "lifecycle-viewmodel-compose" }
jetbrains-compose-navigation = { group = "org.jetbrains.androidx.navigation", name = "navigation-compose", version.ref = "navigation-compose" }
jetbrains-compose-material3-adaptive = { group = "org.jetbrains.compose.material3.adaptive", name = "adaptive", version.ref = "material3adaptive" }
jetbrains-compose-material3-adaptive-layout = { group = "org.jetbrains.compose.material3.adaptive", name = "adaptive-layout", version.ref = "material3adaptive" }
jetbrains-compose-material3-adaptive-navigation = { group = "org.jetbrains.compose.material3.adaptive", name = "adaptive-navigation", version.ref = "material3adaptive" }
# Dependencies of the included build-logic
android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" }

Loading…
Cancel
Save