Skip to content

Commit 555fc2b

Browse files
committed
Gradle 9 update and minor enhancements.
1 parent 4cc086c commit 555fc2b

7 files changed

Lines changed: 104 additions & 74 deletions

File tree

app/build.gradle.kts

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,13 @@ plugins {
44
alias(libs.plugins.android.application)
55
alias(libs.plugins.detekt)
66
alias(libs.plugins.junit5)
7-
alias(libs.plugins.kotlin.android)
87
alias(libs.plugins.kotlin.compose)
98
alias(libs.plugins.kotlin.serialization)
109
alias(libs.plugins.ksp)
1110
alias(libs.plugins.room)
1211
}
1312

1413
android {
15-
namespace = libs.versions.project.application.id.get()
16-
compileSdk = libs.versions.project.compile.sdk.version.get().toInt()
17-
1814
buildFeatures {
1915
buildConfig = true
2016
compose = true
@@ -48,6 +44,11 @@ android {
4844
sourceCompatibility = JavaVersion.VERSION_17
4945
targetCompatibility = JavaVersion.VERSION_17
5046
}
47+
compileSdk {
48+
version = release(libs.versions.project.compile.sdk.version.get().toInt()) {
49+
minorApiLevel = 1
50+
}
51+
}
5152
defaultConfig {
5253
applicationId = libs.versions.project.application.id.get()
5354
minSdk = libs.versions.project.min.sdk.version.get().toInt()
@@ -57,36 +58,39 @@ android {
5758

5859
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
5960
}
60-
detekt {
61-
toolVersion = libs.versions.detekt.get()
62-
config.setFrom(file("../config/detekt/detekt.yml"))
63-
buildUponDefaultConfig = true
64-
autoCorrect = true
65-
}
66-
kotlin {
67-
compilerOptions {
68-
optIn.add("kotlin.RequiresOptIn")
69-
jvmTarget.set(JvmTarget.JVM_17)
70-
}
71-
}
72-
room {
73-
schemaDirectory(path = "$projectDir/schemas")
74-
}
75-
tasks.withType<Test> {
76-
useJUnitPlatform()
61+
namespace = libs.versions.project.application.id.get()
62+
}
63+
detekt {
64+
toolVersion = libs.versions.detekt.get()
65+
config.setFrom(file("../config/detekt/detekt.yml"))
66+
buildUponDefaultConfig = true
67+
autoCorrect = true
68+
}
69+
kotlin {
70+
compilerOptions {
71+
optIn.add("kotlin.RequiresOptIn")
72+
jvmTarget.set(JvmTarget.JVM_17)
7773
}
7874
}
75+
room {
76+
schemaDirectory(path = "$projectDir/schemas")
77+
}
78+
tasks.withType<Test> {
79+
useJUnitPlatform()
80+
}
7981

8082
dependencies {
8183
//region AndroidX Libraries
82-
implementation(libs.annotation)
83-
implementation(libs.appcompat)
84+
implementation(libs.androidx.concurrent.futures)
85+
implementation(libs.androidx.concurrent.futures.ktx)
8486
implementation(libs.androidx.core.ktx)
8587
implementation(libs.androidx.core.splashscreen)
8688
implementation(libs.androidx.lifecycle.runtime.ktx)
8789
implementation(libs.androidx.navigation.compose)
8890
implementation(libs.androidx.security.crypto.ktx)
8991
implementation(libs.androidx.work)
92+
implementation(libs.annotation)
93+
implementation(libs.appcompat)
9094
implementation(libs.bundles.glance)
9195
implementation(libs.material)
9296
implementation(libs.room.runtime)
@@ -102,7 +106,7 @@ dependencies {
102106

103107
//region 3rd Party Libraries
104108
coreLibraryDesugaring(libs.desugar.jdk.libs)
105-
detektPlugins(libs.detekt.compose)
109+
//detektPlugins(libs.detekt.compose)
106110
implementation(libs.coil.compose)
107111
implementation(libs.bundles.koin)
108112
implementation(libs.bundles.koin.compose)

app/src/main/java/com/codermp/composeandroidtemplate/core/presentation/ui/DeviceConfiguration.kt

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
1+
@file:Suppress("MaxLineLength")
2+
13
package com.codermp.composeandroidtemplate.core.presentation.ui
24

3-
import androidx.window.core.layout.WindowHeightSizeClass
5+
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
6+
import androidx.compose.runtime.Composable
47
import androidx.window.core.layout.WindowSizeClass
5-
import androidx.window.core.layout.WindowWidthSizeClass
8+
import androidx.window.core.layout.WindowSizeClass.Companion.HEIGHT_DP_EXPANDED_LOWER_BOUND
9+
import androidx.window.core.layout.WindowSizeClass.Companion.HEIGHT_DP_MEDIUM_LOWER_BOUND
10+
import androidx.window.core.layout.WindowSizeClass.Companion.WIDTH_DP_EXPANDED_LOWER_BOUND
11+
import androidx.window.core.layout.WindowSizeClass.Companion.WIDTH_DP_MEDIUM_LOWER_BOUND
12+
13+
/**
14+
* Composable function that returns the current device configuration.
15+
*/
16+
@Composable
17+
fun currentDeviceConfiguration(): DeviceConfiguration {
18+
val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
19+
return DeviceConfiguration.fromWindowSizeClass(windowSizeClass = windowSizeClass)
20+
}
621

722
/**
823
* Represents the configuration of the device based on the window size class.
@@ -17,28 +32,31 @@ enum class DeviceConfiguration {
1732
TABLET_LANDSCAPE,
1833
DESKTOP;
1934

35+
val isMobile: Boolean
36+
get() = this in listOf(MOBILE_PORTRAIT, MOBILE_LANDSCAPE)
37+
38+
val isWideScreen: Boolean
39+
get() = this in listOf(TABLET_LANDSCAPE, DESKTOP)
40+
2041
companion object {
2142
/**
2243
* Function that returns the appropriate [DeviceConfiguration] based on the provided [windowSizeClass].
2344
* @param windowSizeClass The [WindowSizeClass] of the device.
2445
* @return The corresponding [DeviceConfiguration] based on the window size class.
2546
*/
2647
fun fromWindowSizeClass(windowSizeClass: WindowSizeClass): DeviceConfiguration {
27-
val widthClass = windowSizeClass.windowWidthSizeClass
28-
val heightClass = windowSizeClass.windowHeightSizeClass
29-
30-
return when {
31-
widthClass == WindowWidthSizeClass.COMPACT &&
32-
heightClass == WindowHeightSizeClass.MEDIUM -> MOBILE_PORTRAIT
33-
widthClass == WindowWidthSizeClass.COMPACT &&
34-
heightClass == WindowHeightSizeClass.EXPANDED -> MOBILE_PORTRAIT
35-
widthClass == WindowWidthSizeClass.EXPANDED &&
36-
heightClass == WindowHeightSizeClass.COMPACT -> MOBILE_LANDSCAPE
37-
widthClass == WindowWidthSizeClass.MEDIUM &&
38-
heightClass == WindowHeightSizeClass.EXPANDED -> TABLET_PORTRAIT
39-
widthClass == WindowWidthSizeClass.EXPANDED &&
40-
heightClass == WindowHeightSizeClass.MEDIUM -> TABLET_LANDSCAPE
41-
else -> DESKTOP
48+
return with(receiver = windowSizeClass) {
49+
when {
50+
minWidthDp < WIDTH_DP_MEDIUM_LOWER_BOUND &&
51+
minHeightDp >= HEIGHT_DP_MEDIUM_LOWER_BOUND -> MOBILE_PORTRAIT
52+
minWidthDp >= WIDTH_DP_MEDIUM_LOWER_BOUND &&
53+
minHeightDp < HEIGHT_DP_MEDIUM_LOWER_BOUND -> MOBILE_LANDSCAPE
54+
minWidthDp in WIDTH_DP_MEDIUM_LOWER_BOUND..WIDTH_DP_EXPANDED_LOWER_BOUND &&
55+
minHeightDp >= HEIGHT_DP_MEDIUM_LOWER_BOUND -> TABLET_PORTRAIT
56+
minWidthDp >= WIDTH_DP_EXPANDED_LOWER_BOUND &&
57+
minHeightDp in HEIGHT_DP_MEDIUM_LOWER_BOUND..HEIGHT_DP_EXPANDED_LOWER_BOUND -> TABLET_LANDSCAPE
58+
else -> DESKTOP
59+
}
4260
}
4361
}
4462
}

app/src/main/java/com/codermp/composeandroidtemplate/core/presentation/ui/ObserveAsEvents.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ import kotlinx.coroutines.withContext
1414
* @param flow The [Flow] to observe.
1515
* @param key1 The first key to use for the [LaunchedEffect].
1616
* @param key2 The second key to use for the [LaunchedEffect].
17-
* @param onEvent The function to call when a new event is emitted.
17+
* @param onEvent The suspend function to call when a new event is emitted.
1818
*/
1919
@Composable
2020
fun <T> ObserveAsEvents(
2121
flow: Flow<T>,
2222
key1: Any? = null,
2323
key2: Any? = null,
24-
onEvent: (T) -> Unit
24+
onEvent: suspend (T) -> Unit
2525
) {
2626
val lifecycleOwner = LocalLifecycleOwner.current
2727

gradle.properties

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,8 @@ kotlin.code.style=official
2323
android.nonTransitiveRClass=true
2424
org.gradle.parallel=true
2525
org.gradle.caching=true
26-
org.gradle.configureondemand=true
26+
org.gradle.configureondemand=true
27+
android.uniquePackageNames=false
28+
android.dependency.useConstraints=true
29+
android.r8.strictFullModeForKeepRules=false
30+
android.generateSyncIssueWhenLibraryConstraintsAreEnabled=false

gradle/libs.versions.toml

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,46 @@
11
[versions]
2-
activity-compose = "1.10.1"
3-
agp = "8.12.1"
2+
activity-compose = "1.12.4"
3+
agp = "9.0.0"
44
annotation = "1.9.1"
55
appcompat = "1.7.1"
66
assert-k = "0.28.1"
7-
bson = "5.5.1"
7+
bson = "5.6.3"
88
coil-compose = "2.7.0"
9-
compose-bom = "2025.08.00"
10-
compose-ui-test-manifest = "1.9.0"
9+
compose-bom = "2026.02.00"
10+
compose-ui-test-manifest = "1.10.3"
11+
concurrent-futures = "1.3.0"
1112
core-ktx = "1.17.0"
12-
core-splashscreen = "1.0.1"
13+
core-splashscreen = "1.2.0"
1314
coroutines = "1.10.2"
1415
coroutines-test = "1.10.2"
1516
desugar-jdk-libs = "2.1.5"
16-
detekt = "1.23.8"
17-
detektCompose = "0.4.27"
17+
detekt = "2.0.0-alpha.2"
1818
espresso-core = "3.7.0"
1919
glance = "1.1.1"
2020
junit = "4.13.2"
21-
junit5 = "5.13.4"
22-
junit5-compose = "1.8.0"
23-
junit5-plugin = "1.13.1.0"
21+
junit5 = "6.0.2"
22+
junit5-compose = "2.0.1"
23+
junit5-plugin = "2.0.1"
2424
junit-version = "1.3.0"
25-
koin = "4.1.0"
26-
kotlin = "2.2.10"
27-
kotlinx-serialization = "1.9.0"
28-
ksp = "2.2.10-2.0.2"
29-
ktor = "3.2.3"
30-
ktor-client-logging = "3.2.3"
31-
lifecycle-runtime-ktx = "2.9.2"
32-
material = "1.12.0"
33-
material3 = "1.5.0-alpha02"
34-
material-adaptive = "1.1.0"
25+
koin = "4.1.1"
26+
kotlin = "2.3.10"
27+
kotlinx-serialization = "1.10.0"
28+
ksp = "2.3.4"
29+
ktor = "3.4.0"
30+
ktor-client-logging = "3.4.0"
31+
lifecycle-runtime-ktx = "2.10.0"
32+
material = "1.13.0"
33+
material3 = "1.5.0-alpha14"
34+
material-adaptive = "1.2.0"
3535
material-icons-extended = "1.7.8"
36-
mock-k = "1.14.5"
37-
navigation-compose = "2.9.3"
38-
org-jetbrains-kotlin-jvm = "2.2.10"
39-
room = "2.7.2"
36+
mock-k = "1.14.9"
37+
navigation-compose = "2.9.7"
38+
org-jetbrains-kotlin-jvm = "2.3.10"
39+
room = "2.8.4"
4040
security-crypto-ktx = "1.1.0"
4141
timber = "5.0.1"
4242
turbine = "1.2.1"
43-
work = "2.10.3"
43+
work = "2.11.1"
4444

4545
# Project Versions
4646
project-application-id = "com.codermp.composeandroidtemplate"
@@ -57,6 +57,8 @@ appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "a
5757
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
5858

5959
# AndroidX Libraries
60+
androidx-concurrent-futures = { module = "androidx.concurrent:concurrent-futures", version.ref = "concurrent-futures" }
61+
androidx-concurrent-futures-ktx = { module = "androidx.concurrent:concurrent-futures-ktx", version.ref = "concurrent-futures" }
6062
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "core-ktx" }
6163
androidx-core-splashscreen = { module = "androidx.core:core-splashscreen", version.ref = "core-splashscreen" }
6264
androidx-glance-appwidget = { module = "androidx.glance:glance-appwidget", version.ref = "glance" }
@@ -83,7 +85,6 @@ androidx-material-icons-extended = { module = "androidx.compose.material:materia
8385
# 3rd Party Libraries
8486
coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coil-compose" }
8587
desugar-jdk-libs = { module = "com.android.tools:desugar_jdk_libs", version.ref = "desugar-jdk-libs" }
86-
detekt-compose = { group = "io.nlopez.compose.rules", name = "detekt", version.ref = "detektCompose"}
8788
koin-android-workmanager = { group = "io.insert-koin", name = "koin-androidx-workmanager", version.ref = "koin" }
8889
koin-android = { group = "io.insert-koin", name = "koin-android", version.ref = "koin" }
8990
koin-core = { group = "io.insert-koin", name = "koin-core", version.ref = "koin" }
@@ -122,9 +123,9 @@ turbine = { group = "app.cash.turbine", name = "turbine", version.ref = "turbine
122123
[plugins]
123124
android-application = { id = "com.android.application", version.ref = "agp" }
124125
android-library = { id = "com.android.library", version.ref = "agp" }
125-
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref= "detekt" }
126+
detekt = { id = "dev.detekt", version.ref= "detekt" }
126127
junit5 = { id = "de.mannodermaus.android-junit5", version.ref = "junit5-plugin" }
127-
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
128+
kotlin-android = { id = "org.jetbrains.kotlin.android", version = "2.3.10" }
128129
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
129130
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
130131
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#Fri Jul 25 14:39:22 EDT 2025
22
distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
4-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
4+
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
55
zipStoreBase=GRADLE_USER_HOME
66
zipStorePath=wrapper/dists

settings.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ pluginManagement {
55
gradlePluginPortal()
66
}
77
}
8+
plugins {
9+
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
10+
}
811
dependencyResolutionManagement {
912
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
1013
repositories {

0 commit comments

Comments
 (0)