ganjoorandroid/app/build.gradle.kts
Anas Rashid abcffbc43b Add offline reading, bookmarks, three UI languages and downloads
Reading
- Naskh is now the default face, and both Arabic-script fonts are registered
  at four weights so the text can be thickened for a lit screen.
- Category listings show each poem's opening line, fetched best-effort from
  api.ganjoor.net since the data set doesn't carry excerpts.
- Tap a couplet to save that passage or copy it; a saved passage keeps a
  tappable link back to its poem. Poem text is selectable for plain copying.

Languages
- Persian, Urdu and English, Persian by default whatever the phone's locale,
  applied in attachBaseContext and switchable from the top bar or the sheet.
- English chrome uses Libron (OFL); poems stay naskh or nastaliq throughout.
- Each language gets its own values-* folder: with Farsi only in values/,
  Android was resolving it to the Urdu strings, since a same-script locale
  outranks the default.

Offline
- Downloaded poets mirror the data set's layout under filesDir, so offline
  mode is one lookup rather than a parallel path. Downloads run one poet at
  a time, skip what's on disk, and resume by restarting.
- Downloads screen lists every poet with their portrait and tick boxes for
  picking several, plus storage used, delete, and download-everything behind
  a size warning.
- Offline mode refuses the network and says what's missing rather than
  blaming the connection.

Also: poet sort (Ganjoor's order or alphabetical, via a Persian collator),
RTL nav transitions, an original shamsa launcher icon with a monochrome layer
for themed icons, and preferences written with commit so they survive the
process being killed.

F-Droid: dependenciesInfo off, optional signing so the build works with no
keystore, fastlane metadata in three languages, cleartext traffic disabled.

Verified on an API 36 emulator: downloaded a poet, pulled the emulator's
network, read them offline, and confirmed an undownloaded poet reports being
missing rather than erroring.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-03 23:20:42 +02:00

93 lines
3.1 KiB
Plaintext

import java.util.Properties
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.kotlin.serialization)
}
// Release signing is optional: F-Droid builds from source and signs with its own key, so the
// build has to succeed with no keystore present. Drop a keystore.properties next to settings.gradle
// (storeFile, storePassword, keyAlias, keyPassword) to sign locally; it is gitignored.
val keystoreProperties = Properties().apply {
val file = rootProject.file("keystore.properties")
if (file.exists()) file.inputStream().use { load(it) }
}
android {
namespace = "com.ganjoor.android"
compileSdk {
version = release(37)
}
defaultConfig {
applicationId = "com.ganjoor.android"
minSdk = 24
targetSdk = 37
versionCode = 1
versionName = "0.1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
signingConfigs {
if (keystoreProperties.isNotEmpty()) {
create("release") {
storeFile = rootProject.file(keystoreProperties.getProperty("storeFile"))
storePassword = keystoreProperties.getProperty("storePassword")
keyAlias = keystoreProperties.getProperty("keyAlias")
keyPassword = keystoreProperties.getProperty("keyPassword")
}
}
}
buildTypes {
release {
signingConfig = signingConfigs.findByName("release")
optimization {
enable = true
packageScope = setOf("androidx.**", "kotlin.**", "kotlinx.**")
}
}
}
// The dependency metadata block is signed with a Google key and is not reproducible, so
// F-Droid rejects APKs that carry it.
dependenciesInfo {
includeInApk = false
includeInBundle = false
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
buildFeatures {
compose = true
}
}
dependencies {
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.compose.material.icons.core)
implementation(libs.androidx.compose.ui)
implementation(libs.androidx.compose.ui.graphics)
implementation(libs.androidx.compose.ui.tooling.preview)
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.navigation.compose)
implementation(libs.okhttp)
implementation(libs.kotlinx.serialization.json)
implementation(libs.coil.compose)
implementation(libs.coil.network.okhttp)
testImplementation(libs.junit)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(libs.androidx.junit)
debugImplementation(libs.androidx.compose.ui.test.manifest)
debugImplementation(libs.androidx.compose.ui.tooling)
}