import com.android.build.gradle.internal.api.BaseVariantOutputImpl import org.jetbrains.kotlin.compose.compiler.gradle.ComposeFeatureFlag import java.io.FileInputStream import java.util.Properties plugins { alias(libs.plugins.androidApplication) alias(libs.plugins.kotlinAndroid) alias(libs.plugins.kspAndroid) alias(libs.plugins.roomPlugin) alias(libs.plugins.hiltAndroid) alias(libs.plugins.baselineProfilePlugin) alias(libs.plugins.kotlin.compose.compiler) id("kotlin-parcelize") alias(libs.plugins.kotlinSerialization) } android { namespace = "com.dot.gallery" compileSdk = 35 defaultConfig { applicationId = "com.dot.gallery" minSdk = 30 targetSdk = 35 versionCode = 31020 versionName = "3.1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary = true } base.archivesName.set("Gallery-${versionName}-$versionCode" + mapsApiApplicationPrefix) } lint.baseline = file("lint-baseline.xml") signingConfigs { create("release") { storeFile = file("release_key.jks") storePassword = System.getenv("SIGNING_STORE_PASSWORD") keyAlias = System.getenv("SIGNING_KEY_ALIAS") keyPassword = System.getenv("SIGNING_KEY_PASSWORD") } } buildTypes { getByName("debug") { buildConfigField("String", "MAPS_TOKEN", getApiKey()) applicationIdSuffix = ".debug" versionNameSuffix = "-debug" manifestPlaceholders["appProvider"] = "com.dot.gallery.debug.media_provider" buildConfigField("Boolean", "ALLOW_ALL_FILES_ACCESS", allowAllFilesAccess) buildConfigField( "String", "CONTENT_AUTHORITY", "\"com.dot.gallery.debug.media_provider\"" ) } getByName("release") { manifestPlaceholders += mapOf( "appProvider" to "com.dot.gallery.media_provider" ) isMinifyEnabled = true isShrinkResources = true setProguardFiles( listOf( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) ) signingConfig = signingConfigs.getByName("release") buildConfigField("Boolean", "ALLOW_ALL_FILES_ACCESS", allowAllFilesAccess) buildConfigField("String", "MAPS_TOKEN", getApiKey()) buildConfigField("String", "CONTENT_AUTHORITY", "\"com.dot.gallery.media_provider\"") } create("staging") { initWith(getByName("release")) isMinifyEnabled = false isShrinkResources = false applicationIdSuffix = ".staging" versionNameSuffix = "-staging" manifestPlaceholders["appProvider"] = "com.dot.staging.debug.media_provider" buildConfigField( "String", "CONTENT_AUTHORITY", "\"com.dot.staging.debug.media_provider\"" ) } } compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { jvmTarget = "17" freeCompilerArgs += "-Xcontext-receivers" } buildFeatures { compose = true buildConfig = true } composeCompiler { featureFlags = setOf( ComposeFeatureFlag.OptimizeNonSkippingGroups ) includeSourceInformation = true } packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" } } room { schemaDirectory("$projectDir/schemas/") } dependenciesInfo { // Disables dependency metadata when building APKs. includeInApk = false } flavorDimensions += listOf("abi") productFlavors { create("arm64-v8a") { dimension = "abi" versionCode = 4 + (android.defaultConfig.versionCode ?: 0) * 10 ndk.abiFilters.add("arm64-v8a") } create("armeabi-v7a") { dimension = "abi" versionCode = 3 + (android.defaultConfig.versionCode ?: 0) * 10 ndk.abiFilters.add("armeabi-v7a") } create("x86_64") { dimension = "abi" versionCode = 2 + (android.defaultConfig.versionCode ?: 0) * 10 ndk.abiFilters.add("x86_64") } create("x86") { dimension = "abi" versionCode = 1 + (android.defaultConfig.versionCode ?: 0) * 10 ndk.abiFilters.add("x86") } create("universal") { dimension = "abi" versionCode = 0 + (android.defaultConfig.versionCode ?: 0) * 10 ndk.abiFilters.addAll(listOf("x86", "x86_64", "armeabi-v7a", "arm64-v8a")) } } applicationVariants.all { outputs.forEach { output -> (output as BaseVariantOutputImpl).outputFileName = "Gallery-${versionName}-$versionCode-${productFlavors[0].name}" + mapsApiApplicationPrefix + ".apk" } } } dependencies { runtimeOnly(libs.androidx.profileinstaller) implementation(project(":libs:cropper")) "baselineProfile"(project(mapOf("path" to ":baselineprofile"))) // Core implementation(libs.androidx.core.ktx) implementation(libs.androidx.appcompat) // Core - Lifecycle implementation(libs.androidx.lifecycle.runtime.ktx) implementation(libs.compose.lifecycle.runtime) // Compose implementation(libs.compose.activity) implementation(libs.compose.ui) implementation(libs.compose.ui.graphics) implementation(libs.compose.ui.tooling.preview) implementation(libs.compose.material.icons.extended) implementation(libs.androidx.graphics.shapes) // Compose - Shimmer implementation(libs.compose.shimmer) // Compose - Material3 implementation(libs.compose.material3) implementation(libs.compose.material3.window.size) implementation(libs.androidx.adaptive) implementation(libs.androidx.adaptive.layout) implementation(libs.androidx.adaptive.navigation) // Compose - Accompanists implementation(libs.accompanist.permissions) implementation(libs.androidx.navigation.compose) implementation(libs.accompanist.drawablepainter) // Android MDC - Material implementation(libs.material) // Kotlin - Coroutines implementation(libs.kotlinx.coroutines.core) runtimeOnly(libs.kotlinx.coroutines.android) implementation(libs.kotlinx.serialization.json) // Dagger - Hilt implementation(libs.androidx.hilt.navigation.compose) implementation(libs.dagger.hilt) implementation(libs.androidx.hilt.common) implementation(libs.androidx.hilt.work) ksp(libs.dagger.hilt.compiler) ksp(libs.androidx.hilt.compiler) // Room implementation(libs.room.runtime) ksp(libs.room.compiler) // Kotlin Extensions and Coroutines support for Room implementation(libs.room.ktx) // Coil implementation(libs.jxl.coder.coil) implementation(libs.avif.coder.coil) // Sketch implementation(libs.sketch.compose) implementation(libs.sketch.view) implementation(libs.sketch.animated.gif) implementation(libs.sketch.animated.heif) implementation(libs.sketch.animated.webp) implementation(libs.sketch.extensions.compose) implementation(libs.sketch.http.ktor) implementation(libs.sketch.svg) implementation(libs.sketch.video) // Exo Player implementation(libs.androidx.media3.exoplayer) implementation(libs.androidx.media3.ui) implementation(libs.androidx.media3.session) implementation(libs.androidx.media3.exoplayer.dash) implementation(libs.androidx.media3.exoplayer.hls) implementation(libs.compose.video) // Exif Interface implementation(libs.androidx.exifinterface) // Datastore Preferences implementation(libs.datastore.prefs) // Fuzzy Search implementation(libs.fuzzywuzzy) // Aire implementation(libs.aire) // Pinch to zoom implementation(libs.pinchzoomgrid) // Subsampling implementation(libs.zoomimage.sketch) // Splashscreen implementation(libs.androidx.core.splashscreen) // Jetpack Security implementation(libs.androidx.security.crypto) implementation(libs.androidx.biometric) // Composables - Core implementation(libs.core) // Worker implementation(libs.androidx.work.runtime.ktx) // Composable - Scrollbar implementation(libs.lazycolumnscrollbar) // TensorFlow Lite implementation(libs.tensorflow.lite) implementation(libs.tensorflow.lite.task.vision) implementation(libs.tensorflow.lite.gpu) // Tests testImplementation(libs.junit) androidTestImplementation(libs.androidx.test.ext.junit) debugImplementation(libs.compose.ui.tooling) debugRuntimeOnly(libs.compose.ui.test.manifest) } val mapsApiApplicationPrefix: String get() = if (getApiKey() == "\"DEBUG\"") { "-nomaps" } else { "" } fun getApiKey(): String { val fl = rootProject.file("api.properties") return try { val properties = Properties() properties.load(FileInputStream(fl)) properties.getProperty("MAPS_TOKEN") } catch (e: Exception) { "\"DEBUG\"" } } val allowAllFilesAccess: String get() { val fl = rootProject.file("app.properties") return try { val properties = Properties() properties.load(FileInputStream(fl)) properties.getProperty("ALL_FILES_ACCESS") } catch (e: Exception) { "true" } } @Suppress("UnstableApiUsage") val gitHeadVersion: String get() { return providers.exec { commandLine("git", "show", "-s", "--format=%h", "HEAD") }.standardOutput.asText.get().trim() }