From 0a616c5d36c0ca7a414e9a94bfcfea4cc1605024 Mon Sep 17 00:00:00 2001 From: OHoussein Date: Mon, 6 Jul 2026 16:51:33 +0200 Subject: [PATCH 1/2] Fix deprecation --- build-logic/convention/build.gradle.kts | 4 +- ...linMultiplatformLibraryConventionPlugin.kt | 12 ++--- .../dev/ohoussein/cryptoapp/KotlinAndroid.kt | 48 +++++++++---------- build.gradle.kts | 22 +++------ gradle/libs.versions.toml | 2 - shared/crypto/presentation/build.gradle.kts | 2 +- .../crypto/presentation/core/DatetimeExt.kt | 10 ++-- .../uicomponents/CryptoComponent.kt | 2 +- shared/designsystem/build.gradle.kts | 3 +- .../designsystem/graph/ui/LinearGraph.kt | 2 +- .../designsystem/graph/ui/SparkLineGraph.kt | 2 +- .../ohoussein/cryptoapp/presentation/App.kt | 15 +++--- 12 files changed, 54 insertions(+), 70 deletions(-) diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts index 9b584ce5..75857a51 100644 --- a/build-logic/convention/build.gradle.kts +++ b/build-logic/convention/build.gradle.kts @@ -5,8 +5,8 @@ plugins { group = "dev.ohoussein.cryptoapp.buildlogic" java { - sourceCompatibility = JavaVersion.VERSION_20 - targetCompatibility = JavaVersion.VERSION_20 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } dependencies { diff --git a/build-logic/convention/src/main/kotlin/KotlinMultiplatformLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/KotlinMultiplatformLibraryConventionPlugin.kt index 472c4b9b..07f93906 100644 --- a/build-logic/convention/src/main/kotlin/KotlinMultiplatformLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/KotlinMultiplatformLibraryConventionPlugin.kt @@ -94,13 +94,11 @@ class KotlinMultiplatformLibraryConventionPlugin : Plugin { } } - task("unitTestAll") { - setDependsOn( - listOf( - "cleanTestReleaseUnitTest", "testReleaseUnitTest", - "cleanDesktopTest", "desktopTest", - "cleanIosSimulatorArm64Test", "iosSimulatorArm64Test" - ) + tasks.register("unitTestAll") { + dependsOn( + "cleanTestAndroidHostTest", "testAndroidHostTest", + "cleanDesktopTest", "desktopTest", + "cleanIosSimulatorArm64Test", "iosSimulatorArm64Test", ) } } diff --git a/build-logic/convention/src/main/kotlin/dev/ohoussein/cryptoapp/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/dev/ohoussein/cryptoapp/KotlinAndroid.kt index 0c4abe60..a996011a 100644 --- a/build-logic/convention/src/main/kotlin/dev/ohoussein/cryptoapp/KotlinAndroid.kt +++ b/build-logic/convention/src/main/kotlin/dev/ohoussein/cryptoapp/KotlinAndroid.kt @@ -2,41 +2,41 @@ import com.android.build.api.dsl.CommonExtension import dev.ohoussein.cryptoapp.SdkVersion import org.gradle.api.JavaVersion import org.gradle.api.Project -import org.gradle.kotlin.dsl.provideDelegate import org.gradle.kotlin.dsl.withType import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile internal fun Project.configureKotlinAndroid( commonExtension: CommonExtension, -) = commonExtension.apply { +) { + val warningsAsErrors = (findProperty("warningsAsErrors") as? String).toBoolean() - compileSdk = SdkVersion.COMPILE_SDK_VERSION - with(defaultConfig) { - minSdk = SdkVersion.MIN_SDK_VERSION - } + commonExtension.apply { + compileSdk = SdkVersion.COMPILE_SDK_VERSION + with(defaultConfig) { + minSdk = SdkVersion.MIN_SDK_VERSION + } - compileOptions.sourceCompatibility = JavaVersion.VERSION_20 - compileOptions.targetCompatibility = JavaVersion.VERSION_20 + compileOptions.sourceCompatibility = JavaVersion.VERSION_21 + compileOptions.targetCompatibility = JavaVersion.VERSION_21 - tasks.withType().configureEach { - compilerOptions { - val warningsAsErrors: String? by project - allWarningsAsErrors.set(warningsAsErrors.toBoolean()) + tasks.withType().configureEach { + compilerOptions { + allWarningsAsErrors.set(warningsAsErrors) - jvmTarget.set(JvmTarget.JVM_20) + jvmTarget.set(JvmTarget.JVM_21) - freeCompilerArgs.addAll( - "-opt-in=kotlin.RequiresOptIn", - "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - ) + freeCompilerArgs.addAll( + "-opt-in=kotlin.RequiresOptIn", + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + ) + } } - } - packaging.resources.excludes += arrayOf( - "**/attach_hotspot_windows.dll", - "META-INF/*", - "META-INF/licenses/**", - ) + packaging.resources.excludes += arrayOf( + "**/attach_hotspot_windows.dll", + "META-INF/*", + "META-INF/licenses/**", + ) + } } diff --git a/build.gradle.kts b/build.gradle.kts index 33e9024c..4524223b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,8 +4,6 @@ plugins { alias(libs.plugins.compose.compiler) apply false } -apply(plugin = "com.github.ben-manes.versions") - buildscript { repositories { google() @@ -16,7 +14,6 @@ buildscript { dependencies { classpath(libs.build.android.gradlePlugin) classpath(libs.build.kotlinPlugin) - classpath(libs.build.gradleVersionsPlugin) classpath(libs.build.detekt.plugin) classpath(libs.build.detekt.formatting) classpath(libs.build.paparazzi) @@ -32,28 +29,21 @@ allprojects { } tasks.register("clean").configure { + group = "build" + description = "Deletes the root project build directory." delete("build") } -tasks.withType { - rejectVersionIf { - val version = candidate.version - val stableKeyword = listOf("RELEASE", "FINAL", "GA").any { version.uppercase().contains(it) } - val regex = "^[0-9,.v-]+(-r)?$".toRegex() - val isStable = stableKeyword || regex.matches(version) - isStable.not() - } -} - -task("e2eTests", Exec::class) { +tasks.register("e2eTests") { group = "Verification" description = "Run e2e test on a connected device" workingDir = file("$projectDir/e2e_tests") commandLine = listOf("bash", "test_android.sh") } -task("generateScreenshots", Exec::class) { +tasks.register("generateScreenshots") { group = "Tool" + description = "Generate screenshots on a connected device" workingDir = file("$projectDir/e2e_tests") commandLine = listOf("bash", "generate_screenshots.sh") } @@ -61,7 +51,7 @@ task("generateScreenshots", Exec::class) { subprojects { - apply(plugin = "org.jetbrains.kotlinx.kover") + pluginManager.apply("org.jetbrains.kotlinx.kover") } // Aggregate coverage of every module into the root project's merged report. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8748477c..38d47fda 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,6 @@ koin = "4.1.1" koinCompose = "4.1.1" koinCore = "4.1.1" detektVersion = "1.23.8" -gradleVersionsPluginVersion = "0.53.0" kover = "0.9.8" paparazziVersion = "1.3.5" sqldelight = "2.2.1" @@ -27,7 +26,6 @@ turbineVersion = "1.2.1" [libraries] build-kotlinPlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } build-android-gradlePlugin = { module = "com.android.tools.build:gradle", version.ref = "androidGradlePluginVersion" } -build-gradleVersionsPlugin = { module = "com.github.ben-manes:gradle-versions-plugin", version.ref = "gradleVersionsPluginVersion" } build-detekt-plugin = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detektVersion" } build-detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detektVersion" } build-paparazzi = { module = "app.cash.paparazzi:paparazzi-gradle-plugin", version.ref = "paparazziVersion" } diff --git a/shared/crypto/presentation/build.gradle.kts b/shared/crypto/presentation/build.gradle.kts index c70e3a32..e49a8074 100644 --- a/shared/crypto/presentation/build.gradle.kts +++ b/shared/crypto/presentation/build.gradle.kts @@ -12,7 +12,7 @@ kotlin { implementation(libs.composeMp.foundation) implementation(libs.composeMp.material) implementation(libs.composeMp.ui) - implementation(libs.composeMp.components.uiToolingPreview) + implementation(libs.composeMp.uiToolingPreview) implementation(libs.composeMp.materialIconsExtended) implementation(libs.composeMp.components.resources) implementation(libs.compose.navigation) diff --git a/shared/crypto/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/crypto/presentation/core/DatetimeExt.kt b/shared/crypto/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/crypto/presentation/core/DatetimeExt.kt index 4adc4bbb..96086dac 100644 --- a/shared/crypto/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/crypto/presentation/core/DatetimeExt.kt +++ b/shared/crypto/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/crypto/presentation/core/DatetimeExt.kt @@ -1,20 +1,22 @@ package dev.ohoussein.cryptoapp.crypto.presentation.core import kotlinx.datetime.LocalDateTime +import kotlinx.datetime.Month +import kotlinx.datetime.number @Suppress("LongParameterList") fun LocalDateTime.copy( year: Int = this.year, - monthNumber: Int = this.monthNumber, - dayOfMonth: Int = this.dayOfMonth, + monthNumber: Int = this.month.number, + dayOfMonth: Int = this.day, hour: Int = this.hour, minute: Int = this.minute, second: Int = this.second, nanosecond: Int = this.nanosecond, ) = LocalDateTime( year = year, - monthNumber = monthNumber, - dayOfMonth = dayOfMonth, + month = Month(monthNumber), + day = dayOfMonth, hour = hour, minute = minute, second = second, diff --git a/shared/crypto/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/crypto/presentation/uicomponents/CryptoComponent.kt b/shared/crypto/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/crypto/presentation/uicomponents/CryptoComponent.kt index 49417788..66591b99 100644 --- a/shared/crypto/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/crypto/presentation/uicomponents/CryptoComponent.kt +++ b/shared/crypto/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/crypto/presentation/uicomponents/CryptoComponent.kt @@ -22,7 +22,7 @@ import dev.ohoussein.cryptoapp.crypto.presentation.model.Crypto import dev.ohoussein.cryptoapp.designsystem.graph.ui.SparkLineGraph import dev.ohoussein.cryptoapp.designsystem.theme.NegativeColor import dev.ohoussein.cryptoapp.designsystem.theme.PositiveColor -import org.jetbrains.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.Preview @Composable fun CryptoItem( diff --git a/shared/designsystem/build.gradle.kts b/shared/designsystem/build.gradle.kts index bc77b56a..ef562e83 100644 --- a/shared/designsystem/build.gradle.kts +++ b/shared/designsystem/build.gradle.kts @@ -9,7 +9,6 @@ kotlin { sourceSets { androidMain.dependencies { implementation(libs.compose.ui.tooling) - implementation(libs.composeMp.uiToolingPreview) } commonMain.dependencies { implementation(libs.composeMp.runtime) @@ -18,7 +17,7 @@ kotlin { implementation(libs.composeMp.materialIconsExtended) implementation(libs.composeMp.ui) implementation(libs.composeMp.components.resources) - implementation(libs.composeMp.components.uiToolingPreview) + implementation(libs.composeMp.uiToolingPreview) implementation(libs.koin.compose) implementation(libs.koin.core) implementation(libs.coil.compose) diff --git a/shared/designsystem/src/commonMain/kotlin/dev/ohoussein/cryptoapp/designsystem/graph/ui/LinearGraph.kt b/shared/designsystem/src/commonMain/kotlin/dev/ohoussein/cryptoapp/designsystem/graph/ui/LinearGraph.kt index e40104d5..731ade43 100644 --- a/shared/designsystem/src/commonMain/kotlin/dev/ohoussein/cryptoapp/designsystem/graph/ui/LinearGraph.kt +++ b/shared/designsystem/src/commonMain/kotlin/dev/ohoussein/cryptoapp/designsystem/graph/ui/LinearGraph.kt @@ -19,11 +19,11 @@ import androidx.compose.ui.text.TextMeasurer import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.drawText import androidx.compose.ui.text.rememberTextMeasurer +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import dev.ohoussein.cryptoapp.designsystem.graph.model.GraphPoint import dev.ohoussein.cryptoapp.designsystem.graph.model.GridPoint -import org.jetbrains.compose.ui.tooling.preview.Preview @Suppress("LongMethod") @Composable diff --git a/shared/designsystem/src/commonMain/kotlin/dev/ohoussein/cryptoapp/designsystem/graph/ui/SparkLineGraph.kt b/shared/designsystem/src/commonMain/kotlin/dev/ohoussein/cryptoapp/designsystem/graph/ui/SparkLineGraph.kt index 7c45c254..f6429676 100644 --- a/shared/designsystem/src/commonMain/kotlin/dev/ohoussein/cryptoapp/designsystem/graph/ui/SparkLineGraph.kt +++ b/shared/designsystem/src/commonMain/kotlin/dev/ohoussein/cryptoapp/designsystem/graph/ui/SparkLineGraph.kt @@ -16,7 +16,7 @@ import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import dev.ohoussein.cryptoapp.designsystem.graph.model.GraphPoint -import org.jetbrains.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.Preview @Composable fun SparkLineGraph( diff --git a/shared/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/presentation/App.kt b/shared/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/presentation/App.kt index 2dbebd86..eac94fd1 100644 --- a/shared/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/presentation/App.kt +++ b/shared/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/presentation/App.kt @@ -3,17 +3,14 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.rememberNavController import dev.ohoussein.cryptoapp.crypto.presentation.CryptoFeatNavPath import dev.ohoussein.cryptoapp.crypto.presentation.nav.cryptoAppNavigation -import org.koin.compose.KoinContext @Composable fun SharedApp() { - KoinContext { - val navController = rememberNavController() - NavHost( - navController = navController, - startDestination = CryptoFeatNavPath.HOME, - ) { - cryptoAppNavigation(navController) - } + val navController = rememberNavController() + NavHost( + navController = navController, + startDestination = CryptoFeatNavPath.HOME, + ) { + cryptoAppNavigation(navController) } } From 2ff2efdd2be232f943ab26211fd3b2781125baff Mon Sep 17 00:00:00 2001 From: OHoussein Date: Mon, 6 Jul 2026 17:16:03 +0200 Subject: [PATCH 2/2] Update TopAppBar color --- .../details/CryptoDetailsScreen.kt | 41 +++++++++++++++++++ .../uicomponents/CryptoComponent.kt | 2 +- .../designsystem/base/CryptoAppScaffold.kt | 6 ++- .../designsystem/graph/ui/SparkLineGraph.kt | 2 +- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/shared/crypto/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/crypto/presentation/details/CryptoDetailsScreen.kt b/shared/crypto/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/crypto/presentation/details/CryptoDetailsScreen.kt index 25ccc60c..32865b4f 100644 --- a/shared/crypto/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/crypto/presentation/details/CryptoDetailsScreen.kt +++ b/shared/crypto/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/crypto/presentation/details/CryptoDetailsScreen.kt @@ -7,8 +7,10 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel +import dev.ohoussein.cryptoapp.crypto.presentation.fake.Fake.previewCryptoDetails import dev.ohoussein.cryptoapp.crypto.presentation.graph.CryptoPriceGraph import dev.ohoussein.cryptoapp.crypto.presentation.model.CryptoDetails import dev.ohoussein.cryptoapp.crypto.presentation.model.DataStatus @@ -19,6 +21,7 @@ import dev.ohoussein.cryptoapp.designsystem.base.CryptoAppScaffold import dev.ohoussein.cryptoapp.designsystem.base.CryptoAppTopBar import dev.ohoussein.cryptoapp.designsystem.base.StateError import dev.ohoussein.cryptoapp.designsystem.base.StateLoading +import dev.ohoussein.cryptoapp.designsystem.theme.CryptoAppTheme import org.koin.compose.getKoin import org.koin.core.Koin import org.koin.core.parameter.parametersOf @@ -122,3 +125,41 @@ fun CryptoDetailsContent( Spacer(modifier = Modifier.size(24.dp)) } } + +// The price graph pulls its data from Koin, so this preview renders only the +// header + links which stand on their own. +@Preview +@Composable +private fun PreviewCryptoDetails() { + CryptoAppTheme { + CryptoAppScaffold( + topBar = { + CryptoAppTopBar( + title = with(previewCryptoDetails.base) { "$name ($symbol)" }, + onBackButton = {}, + ) + } + ) { innerPadding -> + Column( + Modifier + .fillMaxSize() + .padding(innerPadding) + .padding(vertical = 12.dp), + ) { + CryptoDetailsHeader( + modifier = Modifier.padding(all = 12.dp), + crypto = previewCryptoDetails, + ) + CryptoLinks( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 24.dp, horizontal = 12.dp), + crypto = previewCryptoDetails, + onHomePageClicked = {}, + onBlockchainSiteClicked = {}, + onSourceCodeClicked = {}, + ) + } + } + } +} diff --git a/shared/crypto/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/crypto/presentation/uicomponents/CryptoComponent.kt b/shared/crypto/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/crypto/presentation/uicomponents/CryptoComponent.kt index 66591b99..9a97b845 100644 --- a/shared/crypto/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/crypto/presentation/uicomponents/CryptoComponent.kt +++ b/shared/crypto/presentation/src/commonMain/kotlin/dev/ohoussein/cryptoapp/crypto/presentation/uicomponents/CryptoComponent.kt @@ -12,6 +12,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import coil3.compose.LocalPlatformContext import coil3.compose.rememberAsyncImagePainter @@ -22,7 +23,6 @@ import dev.ohoussein.cryptoapp.crypto.presentation.model.Crypto import dev.ohoussein.cryptoapp.designsystem.graph.ui.SparkLineGraph import dev.ohoussein.cryptoapp.designsystem.theme.NegativeColor import dev.ohoussein.cryptoapp.designsystem.theme.PositiveColor -import androidx.compose.ui.tooling.preview.Preview @Composable fun CryptoItem( diff --git a/shared/designsystem/src/commonMain/kotlin/dev/ohoussein/cryptoapp/designsystem/base/CryptoAppScaffold.kt b/shared/designsystem/src/commonMain/kotlin/dev/ohoussein/cryptoapp/designsystem/base/CryptoAppScaffold.kt index 0f5825b8..46833f60 100644 --- a/shared/designsystem/src/commonMain/kotlin/dev/ohoussein/cryptoapp/designsystem/base/CryptoAppScaffold.kt +++ b/shared/designsystem/src/commonMain/kotlin/dev/ohoussein/cryptoapp/designsystem/base/CryptoAppScaffold.kt @@ -7,6 +7,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import cryptoapp.shared.designsystem.generated.resources.Res import cryptoapp.shared.designsystem.generated.resources.core_back @@ -59,8 +60,9 @@ fun CryptoAppTopBar( } } }, - contentColor = MaterialTheme.colors.onPrimary, - backgroundColor = MaterialTheme.colors.primary, + elevation = 0.dp, + contentColor = MaterialTheme.colors.onSurface, + backgroundColor = Color.Transparent, windowInsets = WindowInsets.statusBars, ) } diff --git a/shared/designsystem/src/commonMain/kotlin/dev/ohoussein/cryptoapp/designsystem/graph/ui/SparkLineGraph.kt b/shared/designsystem/src/commonMain/kotlin/dev/ohoussein/cryptoapp/designsystem/graph/ui/SparkLineGraph.kt index f6429676..0fe79077 100644 --- a/shared/designsystem/src/commonMain/kotlin/dev/ohoussein/cryptoapp/designsystem/graph/ui/SparkLineGraph.kt +++ b/shared/designsystem/src/commonMain/kotlin/dev/ohoussein/cryptoapp/designsystem/graph/ui/SparkLineGraph.kt @@ -13,10 +13,10 @@ import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.graphics.drawscope.Fill import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import dev.ohoussein.cryptoapp.designsystem.graph.model.GraphPoint -import androidx.compose.ui.tooling.preview.Preview @Composable fun SparkLineGraph(