import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { alias(libs.plugins.androidApplication) alias(libs.plugins.googleServices) alias(libs.plugins.jetbrainsComposeCompiler) alias(libs.plugins.serialization) } def getCurrentBranch() { try { def branch = 'git rev-parse --abbrev-ref HEAD'.execute().text.trim() return branch } catch (Exception e) { println "Could not determine git branch: ${e.message}" return "unknown" } } def generateVersionName(String baseVersion) { def currentBranch = getCurrentBranch() if (currentBranch == "main" || currentBranch == "master" || currentBranch == "unknown" || currentBranch == "HEAD") { return baseVersion } else { // Clean branch name for version (replace special characters) def cleanBranch = currentBranch.replaceAll(/[^a-zA-Z0-9\-_]/, "-") // Limit branch name to maximum 20 characters if (cleanBranch.length() > 20) { cleanBranch = cleanBranch.substring(0, 20) } return "${baseVersion}-${cleanBranch}" } } // Workaround: stability.analyzer plugin doesn't declare task dependencies properly for Gradle 9.x afterEvaluate { def stabilityNames = tasks.names.findAll { it.contains("StabilityCheck") } def compileNames = tasks.names.findAll { it.matches("compile.*UnitTestKotlin") } stabilityNames.each { scName -> compileNames.each { ctName -> tasks.named(scName).configure { mustRunAfter(tasks.named(ctName)) } } } } android { namespace = 'com.vitorpamplona.amethyst' compileSdk = libs.versions.android.compileSdk.get().toInteger() defaultConfig { applicationId = "com.vitorpamplona.amethyst" minSdk = libs.versions.android.minSdk.get().toInteger() targetSdk = libs.versions.android.targetSdk.get().toInteger() versionCode = 442 versionName = generateVersionName(libs.versions.app.get()) buildConfigField "String", "RELEASE_NOTES_ID", "\"be99e8c8d4df0f54b44eb6c96976ccb38baeea0192436a1c6fc8bc5e930da6b0\"" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary = true } resourceConfigurations += [ 'ar', 'ar-rSA', 'bn-rBD', 'cs', 'cs-rCZ', 'cy-rGB', 'da-rDK', 'de', 'de-rDE', 'el-rGR', 'en-rGB', 'eo', 'eo-rUY', 'es', 'es-rES', 'es-rMX', 'es-rUS', 'et-rEE', 'fa', 'fa-rIR', 'fi-rFI', 'fo-rFO', 'fr', 'fr-rCA', 'fr-rFR', 'gu-rIN', 'hi-rIN', 'hr-rHR', 'hu', 'hu-rHU', 'in', 'in-rID', 'it-rIT', 'iw-rIL', 'ja', 'ja-rJP', 'kk-rKZ', 'ko-rKR', 'ks-rIN', 'ku-rTR', 'lt-rLT', 'ne-rNP', 'nl', 'nl-rBE', 'nl-rNL', 'pcm-rNG', 'pl-rPL', 'pt-rBR', 'pt-rPT', 'ru', 'ru-rRU', 'ru-rUA', 'sa-rIN', 'sl-rSI', 'so-rSO', 'sr-rSP', 'ss-rZA', 'sv-rSE', 'sw-rKE', 'sw-rTZ', 'ta', 'ta-rIN', 'th', 'th-rTH', 'tr', 'tr-rTR', 'uk', 'uk-rUA', 'ur-rIN', 'uz-rUZ', 'vi-rVN', 'zh', 'zh-rCN', 'zh-rHK', 'zh-rSG', 'zh-rTW' ] } buildTypes { release { proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), 'proguard-rules.pro' minifyEnabled = true } debug { applicationIdSuffix '.debug' versionNameSuffix '-DEBUG' resValue "string", "app_name", "@string/app_name_debug" } create("benchmark") { initWith(getByName("release")) applicationIdSuffix '.benchmark' versionNameSuffix '-BENCHMARK' resValue "string", "app_name", "@string/app_name_benchmark" profileable = true signingConfig = signingConfigs.debug } } // TODO: remove this when lightcompressor uses one MP4 parser only packaging { resources { resources.pickFirsts.add('builddef.lst') resources.pickFirsts.add('META-INF/LICENSE.md') resources.pickFirsts.add('META-INF/LICENSE-notice.md') } } flavorDimensions = ["channel"] productFlavors { play { getIsDefault().set(true) dimension "channel" } fdroid { dimension "channel" } } splits { abi { enable = true reset() include "x86", "x86_64", "arm64-v8a", "armeabi-v7a" universalApk = true } } compileOptions { sourceCompatibility JavaVersion.VERSION_21 targetCompatibility JavaVersion.VERSION_21 } buildFeatures { compose = true buildConfig = true resValues = true } packagingOptions { resources { excludes += ['/META-INF/{AL2.0,LGPL2.1}', '**/libscrypt.dylib'] } } lint { disable 'MissingTranslation' } testOptions { unitTests.returnDefaultValues = true } } // TODO: until google merges and unifiedpush updates https://github.com/tink-crypto/tink-java-apps/pull/5 configurations.all { def tink = "com.google.crypto.tink:tink-android:1.17.0" resolutionStrategy { force(tink) dependencySubstitution { substitute module('com.google.crypto.tink:tink') using module(tink) } } } kotlin { compilerOptions { jvmTarget = JvmTarget.JVM_21 } } composeCompiler { reportsDestination = layout.buildDirectory.dir("compose_compiler") metricsDestination = layout.buildDirectory.dir("compose_compiler") } dependencies { implementation platform(libs.androidx.compose.bom) implementation project(path: ':quartz') implementation project(path: ':commons') implementation project(path: ':ammolite') implementation project(path: ':nestsClient') implementation libs.androidx.core.ktx implementation libs.androidx.activity.compose implementation libs.androidx.ui implementation libs.androidx.ui.graphics implementation libs.androidx.ui.tooling.preview // Needs this to open gallery / image upload implementation libs.androidx.fragment.ktx // Navigation implementation libs.androidx.navigation.compose // Material 3 Design implementation libs.androidx.material3 implementation libs.androidx.material.icons // Adaptive Layout / Two Pane implementation libs.androidx.material3.windowSize implementation libs.accompanist.adaptive // Lifecycle implementation libs.androidx.lifecycle.runtime.ktx implementation libs.androidx.lifecycle.runtime.compose implementation libs.androidx.lifecycle.viewmodel.compose // Zoomable images implementation libs.zoomable // Biometrics implementation libs.androidx.biometric.ktx // Background Work implementation libs.androidx.work.runtime.ktx // Websockets API implementation libs.okhttp implementation libs.okhttpCoroutines // Encrypted Key Storage implementation libs.androidx.security.crypto.ktx implementation libs.androidx.datastore.preferences // view videos implementation libs.androidx.media3.exoplayer implementation libs.androidx.media3.exoplayer.hls implementation libs.androidx.media3.ui.compose.material3 implementation libs.androidx.media3.session // important for proxy / tor implementation libs.androidx.media3.datasource.okhttp // Load images from the web. implementation libs.coil.compose // view gifs implementation libs.coil.gif // view svgs implementation libs.coil.svg // enables network for coil implementation libs.coil.okhttp // loads thumbnails for media3 // TODO: Replace this to the FrameExtractor in media 3 // when FrameExtractor accepts custom data sources. implementation(libs.coil.video) // Permission to upload pictures: implementation libs.accompanist.permissions // For QR generation implementation libs.zxing implementation libs.zxing.embedded // Markdown //implementation "com.halilibo.compose-richtext:richtext-ui:0.16.0" //implementation "com.halilibo.compose-richtext:richtext-ui-material:0.16.0" //implementation "com.halilibo.compose-richtext:richtext-commonmark:0.16.0" // Markdown (With fix for full-image bleeds) implementation libs.markdown.ui implementation libs.markdown.ui.material3 implementation libs.markdown.commonmark // Language picker and Theme chooser implementation libs.androidx.appcompat // Dynamically adjust between phone and tablet UI implementation libs.androidx.window.core.android // Local model for language identification playImplementation libs.google.mlkit.language.id // Google services model the translate text playImplementation libs.google.mlkit.translate // On-device AI writing assistance (Gemini Nano via AICore) playImplementation libs.google.mlkit.genai.proofreading playImplementation libs.google.mlkit.genai.prompt playImplementation libs.google.mlkit.genai.rewriting // PushNotifications playImplementation platform(libs.firebase.bom) playImplementation libs.firebase.messaging //PushNotifications(FDroid) fdroidImplementation libs.unifiedpush // Charts implementation libs.vico.charts.compose implementation libs.vico.charts.m3 // Waveform visualizer implementation libs.audiowaveform // Video compression lib implementation libs.abedElazizShe.video.compressor.fork // Image compression lib implementation libs.zelory.image.compressor // EXIF metadata stripping implementation libs.androidx.exifinterface // Voice anonymization DSP implementation libs.tarsosdsp // WebRTC for voice/video calls implementation libs.stream.webrtc.android // Cbor for cashuB format implementation libs.kotlinx.serialization.cbor // Kotlin serialization for the times where we need the Json tree and performance is not that important. implementation(libs.kotlinx.serialization.json) testImplementation libs.junit testImplementation libs.mockk testImplementation libs.kotlinx.coroutines.test androidTestImplementation platform(libs.androidx.compose.bom) androidTestImplementation libs.androidx.junit androidTestImplementation libs.androidx.junit.ktx androidTestImplementation libs.androidx.espresso.core androidTestImplementation libs.androidx.ui.test.junit4 androidTestImplementation libs.mockk.android debugImplementation platform(libs.androidx.compose.bom) debugImplementation libs.androidx.ui.tooling debugImplementation libs.androidx.ui.test.manifest implementation libs.androidx.camera.core implementation libs.androidx.camera.camera2 implementation libs.androidx.camera.lifecycle implementation libs.androidx.camera.view implementation libs.androidx.camera.extensions }