haunt / files / app / build.gradle.kts
build.gradle.kts
| 1 | plugins { |
| 2 | alias(libs.plugins.android.application) |
| 3 | alias(libs.plugins.kotlin.android) |
| 4 | } |
| 5 | |
| 6 | android { |
| 7 | namespace = "net.fuzzyworld.haunt" |
| 8 | compileSdk = 35 |
| 9 | |
| 10 | defaultConfig { |
| 11 | applicationId = "net.fuzzyworld.haunt" |
| 12 | minSdk = 28 |
| 13 | targetSdk = 35 |
| 14 | versionCode = 1 |
| 15 | versionName = "1.0" |
| 16 | } |
| 17 | |
| 18 | buildTypes { |
| 19 | release { |
| 20 | isMinifyEnabled = false |
| 21 | } |
| 22 | } |
| 23 | |
| 24 | compileOptions { |
| 25 | sourceCompatibility = JavaVersion.VERSION_17 |
| 26 | targetCompatibility = JavaVersion.VERSION_17 |
| 27 | } |
| 28 | |
| 29 | kotlinOptions { |
| 30 | jvmTarget = "17" |
| 31 | } |
| 32 | |
| 33 | buildFeatures { |
| 34 | viewBinding = true |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | // --------------------------------------------------------------------------- |
| 39 | // generateIcons task |
| 40 | // |
| 41 | // Reads location.png from the project root and writes all mipmap PNGs plus |
| 42 | // the adaptive-icon foreground. Run with: |
| 43 | // ./gradlew :app:generateIcons |
| 44 | // |
| 45 | // The source file and background color are the only things you'd ever change. |
| 46 | // --------------------------------------------------------------------------- |
| 47 | tasks.register("generateIcons") { |
| 48 | val src = rootProject.file("location.png") |
| 49 | val resDir = file("src/main/res") |
| 50 | val bgColor = "#ADD8E6" |
| 51 | |
| 52 | inputs.file(src) |
| 53 | outputs.dir(resDir) |
| 54 | |
| 55 | doLast { |
| 56 | if (!src.exists()) error("Source icon not found: ${src.absolutePath}") |
| 57 | |
| 58 | fun magick(vararg args: String) { |
| 59 | val cmd = listOf("magick") + args.toList() |
| 60 | val proc = ProcessBuilder(cmd).redirectErrorStream(true).start() |
| 61 | val out = proc.inputStream.bufferedReader().readText() |
| 62 | val exit = proc.waitFor() |
| 63 | if (exit != 0) error("magick failed (exit $exit):\n$out") |
| 64 | } |
| 65 | |
| 66 | data class Density(val dir: String, val size: Int) |
| 67 | val densities = listOf( |
| 68 | Density("mipmap-mdpi", 48), |
| 69 | Density("mipmap-hdpi", 72), |
| 70 | Density("mipmap-xhdpi", 96), |
| 71 | Density("mipmap-xxhdpi", 144), |
| 72 | Density("mipmap-xxxhdpi", 192), |
| 73 | ) |
| 74 | |
| 75 | // Legacy flat icons — background baked in |
| 76 | for ((dir, size) in densities) { |
| 77 | val out = resDir.resolve("$dir/ic_launcher.png") |
| 78 | out.parentFile.mkdirs() |
| 79 | magick(src.absolutePath, "-background", bgColor, "-flatten", |
| 80 | "-resize", "${size}x${size}", out.absolutePath) |
| 81 | println(" ✓ $dir/ic_launcher.png (${size}×${size})") |
| 82 | } |
| 83 | |
| 84 | // Adaptive foreground — transparent, centered in 432×432 safe-zone canvas |
| 85 | val fg = resDir.resolve("drawable/ic_launcher_foreground.png") |
| 86 | fg.parentFile.mkdirs() |
| 87 | magick(src.absolutePath, "-background", "none", |
| 88 | "-resize", "264x264", "-gravity", "center", "-extent", "432x432", |
| 89 | fg.absolutePath) |
| 90 | println(" ✓ drawable/ic_launcher_foreground.png (432×432)") |
| 91 | |
| 92 | // Web favicons — written to repo root for GitLab/GitHub project pages |
| 93 | val root = rootProject.projectDir |
| 94 | magick(src.absolutePath, "-background", bgColor, "-flatten", |
| 95 | "(", "-clone", "0", "-resize", "16x16", ")", |
| 96 | "(", "-clone", "0", "-resize", "32x32", ")", |
| 97 | "(", "-clone", "0", "-resize", "48x48", ")", |
| 98 | "-delete", "0", |
| 99 | root.resolve("favicon.ico").absolutePath) |
| 100 | println(" ✓ favicon.ico (16/32/48 px layers)") |
| 101 | |
| 102 | magick(src.absolutePath, "-background", bgColor, "-flatten", |
| 103 | "-resize", "32x32", |
| 104 | root.resolve("favicon.png").absolutePath) |
| 105 | println(" ✓ favicon.png (32×32)") |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | dependencies { |
| 110 | implementation(libs.androidx.appcompat) |
| 111 | implementation(libs.androidx.activity.ktx) |
| 112 | implementation(libs.androidx.lifecycle.viewmodel) |
| 113 | implementation(libs.androidx.lifecycle.runtime) |
| 114 | implementation(libs.androidx.recyclerview) |
| 115 | implementation(libs.kotlinx.coroutines.android) |
| 116 | implementation(libs.retrofit) |
| 117 | implementation(libs.retrofit.gson) |
| 118 | implementation(libs.okhttp) |
| 119 | implementation(libs.gson) |
| 120 | } |