Skip to content
Merged
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
62 changes: 38 additions & 24 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import dev.detekt.gradle.Detekt
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.detekt)
alias(libs.plugins.junit5)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.ksp)
alias(libs.plugins.room)
}

android {
namespace = libs.versions.project.application.id.get()
compileSdk = libs.versions.project.compile.sdk.version.get().toInt()

buildFeatures {
buildConfig = true
compose = true
Expand Down Expand Up @@ -48,6 +45,11 @@ android {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
compileSdk {
version = release(libs.versions.project.compile.sdk.version.get().toInt()) {
minorApiLevel = 1
}
}
defaultConfig {
applicationId = libs.versions.project.application.id.get()
minSdk = libs.versions.project.min.sdk.version.get().toInt()
Expand All @@ -57,36 +59,36 @@ android {

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
detekt {
toolVersion = libs.versions.detekt.get()
config.setFrom(file("../config/detekt/detekt.yml"))
buildUponDefaultConfig = true
autoCorrect = true
}
kotlin {
compilerOptions {
optIn.add("kotlin.RequiresOptIn")
jvmTarget.set(JvmTarget.JVM_17)
}
}
room {
schemaDirectory(path = "$projectDir/schemas")
}
tasks.withType<Test> {
useJUnitPlatform()
namespace = libs.versions.project.application.id.get()
}
detekt {
toolVersion = libs.versions.detekt.get()
config.setFrom(file("../config/detekt/detekt.yml"))
buildUponDefaultConfig = true
autoCorrect = true
}
kotlin {
compilerOptions {
optIn.add("kotlin.RequiresOptIn")
jvmTarget.set(JvmTarget.JVM_17)
}
}
room {
schemaDirectory(path = "$projectDir/schemas")
}

dependencies {
//region AndroidX Libraries
implementation(libs.annotation)
implementation(libs.appcompat)
implementation(libs.androidx.concurrent.futures)
implementation(libs.androidx.concurrent.futures.ktx)
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.core.splashscreen)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.navigation.compose)
implementation(libs.androidx.security.crypto.ktx)
implementation(libs.androidx.work)
implementation(libs.annotation)
implementation(libs.appcompat)
implementation(libs.bundles.glance)
implementation(libs.material)
implementation(libs.room.runtime)
Expand All @@ -102,7 +104,6 @@ dependencies {

//region 3rd Party Libraries
coreLibraryDesugaring(libs.desugar.jdk.libs)
detektPlugins(libs.detekt.compose)
implementation(libs.coil.compose)
implementation(libs.bundles.koin)
implementation(libs.bundles.koin.compose)
Expand Down Expand Up @@ -144,4 +145,17 @@ dependencies {
androidTestImplementation(libs.mockk.android)
androidTestImplementation(libs.turbine)
//endregion
}

tasks.withType<Test> {
useJUnitPlatform()
}

tasks.withType<Detekt>().configureEach {
reports {
checkstyle.required.set(true)
html.required.set(true)
sarif.required.set(true)
markdown.required.set(true)
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("MagicNumber")

package com.codermp.composeandroidtemplate.core.presentation.designsystem.theme

import androidx.compose.ui.graphics.Color
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
@file:Suppress("MaxLineLength")

package com.codermp.composeandroidtemplate.core.presentation.ui

import androidx.window.core.layout.WindowHeightSizeClass
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.runtime.Composable
import androidx.window.core.layout.WindowSizeClass
import androidx.window.core.layout.WindowWidthSizeClass
import androidx.window.core.layout.WindowSizeClass.Companion.HEIGHT_DP_EXPANDED_LOWER_BOUND
import androidx.window.core.layout.WindowSizeClass.Companion.HEIGHT_DP_MEDIUM_LOWER_BOUND
import androidx.window.core.layout.WindowSizeClass.Companion.WIDTH_DP_EXPANDED_LOWER_BOUND
import androidx.window.core.layout.WindowSizeClass.Companion.WIDTH_DP_MEDIUM_LOWER_BOUND

/**
* Composable function that returns the current device configuration.
*/
@Composable
fun currentDeviceConfiguration(): DeviceConfiguration {
val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
return DeviceConfiguration.fromWindowSizeClass(windowSizeClass = windowSizeClass)
}

/**
* Represents the configuration of the device based on the window size class.
Expand All @@ -17,28 +32,31 @@ enum class DeviceConfiguration {
TABLET_LANDSCAPE,
DESKTOP;

val isMobile: Boolean
get() = this in listOf(MOBILE_PORTRAIT, MOBILE_LANDSCAPE)

val isWideScreen: Boolean
get() = this in listOf(TABLET_LANDSCAPE, DESKTOP)

companion object {
/**
* Function that returns the appropriate [DeviceConfiguration] based on the provided [windowSizeClass].
* @param windowSizeClass The [WindowSizeClass] of the device.
* @return The corresponding [DeviceConfiguration] based on the window size class.
*/
fun fromWindowSizeClass(windowSizeClass: WindowSizeClass): DeviceConfiguration {
val widthClass = windowSizeClass.windowWidthSizeClass
val heightClass = windowSizeClass.windowHeightSizeClass

return when {
widthClass == WindowWidthSizeClass.COMPACT &&
heightClass == WindowHeightSizeClass.MEDIUM -> MOBILE_PORTRAIT
widthClass == WindowWidthSizeClass.COMPACT &&
heightClass == WindowHeightSizeClass.EXPANDED -> MOBILE_PORTRAIT
widthClass == WindowWidthSizeClass.EXPANDED &&
heightClass == WindowHeightSizeClass.COMPACT -> MOBILE_LANDSCAPE
widthClass == WindowWidthSizeClass.MEDIUM &&
heightClass == WindowHeightSizeClass.EXPANDED -> TABLET_PORTRAIT
widthClass == WindowWidthSizeClass.EXPANDED &&
heightClass == WindowHeightSizeClass.MEDIUM -> TABLET_LANDSCAPE
else -> DESKTOP
return with(receiver = windowSizeClass) {
when {
minWidthDp < WIDTH_DP_MEDIUM_LOWER_BOUND &&
minHeightDp >= HEIGHT_DP_MEDIUM_LOWER_BOUND -> MOBILE_PORTRAIT
minWidthDp >= WIDTH_DP_MEDIUM_LOWER_BOUND &&
minHeightDp < HEIGHT_DP_MEDIUM_LOWER_BOUND -> MOBILE_LANDSCAPE
minWidthDp in WIDTH_DP_MEDIUM_LOWER_BOUND..WIDTH_DP_EXPANDED_LOWER_BOUND &&
minHeightDp >= HEIGHT_DP_MEDIUM_LOWER_BOUND -> TABLET_PORTRAIT
minWidthDp >= WIDTH_DP_EXPANDED_LOWER_BOUND &&
minHeightDp in HEIGHT_DP_MEDIUM_LOWER_BOUND..HEIGHT_DP_EXPANDED_LOWER_BOUND -> TABLET_LANDSCAPE
else -> DESKTOP
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ import kotlinx.coroutines.withContext
* @param flow The [Flow] to observe.
* @param key1 The first key to use for the [LaunchedEffect].
* @param key2 The second key to use for the [LaunchedEffect].
* @param onEvent The function to call when a new event is emitted.
* @param onEvent The suspend function to call when a new event is emitted.
*/
@Composable
fun <T> ObserveAsEvents(
flow: Flow<T>,
key1: Any? = null,
key2: Any? = null,
onEvent: (T) -> Unit
onEvent: suspend (T) -> Unit
) {
val lifecycleOwner = LocalLifecycleOwner.current

Expand Down
Loading
Loading