diff --git a/app/src/main/java/com/ganjoor/android/ui/PoetsScreen.kt b/app/src/main/java/com/ganjoor/android/ui/PoetsScreen.kt index b10ad89..7e456f0 100644 --- a/app/src/main/java/com/ganjoor/android/ui/PoetsScreen.kt +++ b/app/src/main/java/com/ganjoor/android/ui/PoetsScreen.kt @@ -55,6 +55,11 @@ import coil3.compose.AsyncImage import java.text.Collator import java.util.Locale import com.ganjoor.android.R +import com.ganjoor.android.ui.theme.downloaded +import com.ganjoor.android.data.Offline +import com.ganjoor.android.data.Downloads +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material.icons.filled.CheckCircle import com.ganjoor.android.data.Ganjoor import com.ganjoor.android.data.PoetRef @@ -249,6 +254,49 @@ private fun PinMark(modifier: Modifier = Modifier) { ) } +/** + * Fetch a poet's poems, or say they are already here. Three states and no menu: downloading shows + * its progress and cancels on a tap, downloaded is a green tick, and anything else offers the + * download. Deleting stays on the downloads page, where the sizes are — a tap next to a poet's + * name should never be the thing that throws their poems away. + */ +@Composable +private fun DownloadAction(slug: String) { + val progress = Downloads.running[slug] + val saved = remember(slug, Downloads.revision) { Offline.isSaved(slug) } + + when { + progress != null -> IconButton(onClick = { Downloads.cancel(slug) }) { + CircularProgressIndicator( + strokeWidth = 2.dp, + modifier = Modifier.size(18.dp), + ) + } + + // In a box the size of an IconButton, even though nothing here is tappable: a bare icon + // sits where the button's padding would have put it, so the ticks and the arrows would + // not line up down the column. + saved -> Box( + modifier = Modifier.size(48.dp), + contentAlignment = Alignment.Center, + ) { + Icon( + imageVector = Icons.Default.CheckCircle, + contentDescription = stringResource(R.string.downloaded_poet), + tint = MaterialTheme.colorScheme.downloaded, + ) + } + + else -> IconButton(onClick = { Downloads.start(slug) }) { + Icon( + painter = painterResource(R.drawable.ic_download), + contentDescription = stringResource(R.string.download), + tint = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + } +} + /** One poet as a row, for readers who would rather scan names than faces. */ @Composable private fun PoetRow(poet: PoetRef, pinned: Boolean, onClick: () -> Unit, onPin: () -> Unit) { @@ -271,7 +319,15 @@ private fun PoetRow(poet: PoetRef, pinned: Boolean, onClick: () -> Unit, onPin: ) } }, - trailingContent = { if (pinned) PinMark() }, + trailingContent = { + Row( + horizontalArrangement = Arrangement.spacedBy(4.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + if (pinned) PinMark() + DownloadAction(poet.slug) + } + }, modifier = Modifier.combinedClickable(onClick = onClick, onLongClick = onPin), ) } diff --git a/app/src/main/java/com/ganjoor/android/ui/theme/Theme.kt b/app/src/main/java/com/ganjoor/android/ui/theme/Theme.kt index 3be6baf..2872848 100644 --- a/app/src/main/java/com/ganjoor/android/ui/theme/Theme.kt +++ b/app/src/main/java/com/ganjoor/android/ui/theme/Theme.kt @@ -9,6 +9,7 @@ import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable import androidx.compose.runtime.SideEffect import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.luminance import androidx.compose.ui.graphics.lerp import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalView @@ -202,3 +203,13 @@ fun GanjoorTheme( content = content, ) } + +/** + * The green on a poet whose poems are already on the device. + * + * Material's palette has no success colour, and a fixed green goes muddy on the sepia schemes and + * glares on OLED black. Picking by the surface's luminance covers all five schemes without each + * of them having to declare one. + */ +val ColorScheme.downloaded: Color + get() = if (surface.luminance() < 0.5f) Color(0xFF81C784) else Color(0xFF2E7D32) diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 0b18f2c..58ad7ff 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -113,4 +113,5 @@ برای نگه‌داشتن یک شاعر در اینجا، انگشت را روی او نگه دارید نمایش کارتی نمایش فهرستی + پیش‌تر دریافت شده diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index 43fa119..c6a95da 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -113,4 +113,5 @@ کسی شاعر کو یہاں رکھنے کے لیے اُس پر دبا کر رکھیں کارڈ کی صورت فہرست کی صورت + پہلے سے محفوظ ہے diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c7f3e98..fd37aa3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -118,4 +118,5 @@ Press and hold a poet to keep them here Show as cards Show as a list + Already downloaded diff --git a/fastlane/metadata/android/en-US/changelogs/5.txt b/fastlane/metadata/android/en-US/changelogs/5.txt index 6f76539..eb371a8 100644 --- a/fastlane/metadata/android/en-US/changelogs/5.txt +++ b/fastlane/metadata/android/en-US/changelogs/5.txt @@ -6,3 +6,6 @@ alphabetical listing a tap away. Until you pin anything the shelf is simply Ganjoor's order, so there is never an empty screen. Poets can be shown as cards or as a list, whichever reads better. + +Each poet in the list view carries a download button, and a green tick once their +poems are on the device. Text only — recitations are still streamed when you play them. diff --git a/fastlane/metadata/android/fa/changelogs/5.txt b/fastlane/metadata/android/fa/changelogs/5.txt index b9cd46b..733fbca 100644 --- a/fastlane/metadata/android/fa/changelogs/5.txt +++ b/fastlane/metadata/android/fa/changelogs/5.txt @@ -6,3 +6,6 @@ صفحه‌ای خالی نمی‌بینید. شاعران را می‌توان کارتی یا فهرستی دید، هرکدام که خواناتر است. + +هر شاعر در نمایش فهرستی یک دکمهٔ دریافت دارد، و پس از ذخیره‌شدن شعرهایش یک تیک سبز. +فقط متن؛ خوانش‌ها همچنان هنگام پخش از اینترنت می‌آیند. diff --git a/fastlane/metadata/android/ur/changelogs/5.txt b/fastlane/metadata/android/ur/changelogs/5.txt index 5b6e2f3..49cc684 100644 --- a/fastlane/metadata/android/ur/changelogs/5.txt +++ b/fastlane/metadata/android/ur/changelogs/5.txt @@ -7,3 +7,6 @@ سو خالی صفحہ کبھی نہیں ملتا۔ شاعروں کو کارڈ کی صورت یا فہرست کی صورت، جو بہتر لگے، دیکھا جا سکتا ہے۔ + +فہرست کی صورت میں ہر شاعر کے ساتھ ڈاؤن لوڈ کا بٹن ہے، اور اُن کا کلام محفوظ ہو جانے پر +سبز نشان۔ صرف متن؛ تلاوتیں اب بھی سنتے وقت آن لائن چلتی ہیں۔ diff --git a/releases/README.md b/releases/README.md index a63eb5d..f65eb4a 100644 --- a/releases/README.md +++ b/releases/README.md @@ -12,7 +12,7 @@ from source and signs with its own key, so these are for direct installation onl | 0.2.0 | 2 | `d92445f` | Share a poem, couplet or selection; look a word up from any app's selection menu; the optional AI assistant. | | 0.2.1 | 3 | `ec05989` | Assistant answers in the page rather than over it, a visible chevron for each couplet's actions, and answers remembered so scrolling doesn't re-ask. | | 0.2.2 | 4 | `d7568d1` | Credits Material Symbols for the glyphs, and states the terms around the optional assistant. | -| 0.3.0 | 5 | `HEAD` | Pin poets to the home screen: three views (pinned, Ganjoor's order, alphabetical), as cards or a list. | +| 0.3.0 | 5 | `HEAD` | Pin poets to the home screen: three views (pinned, Ganjoor's order, alphabetical), as cards or a list, with a download control on each row. | ## Checksums @@ -21,7 +21,7 @@ from source and signs with its own key, so these are for direct installation onl 43d78b773efca2b1aa2bf790c689b3086389d66c4ea0ffb72c9dba8bddb50770 ganjoor-0.2.0.apk 5163554eb01845c131c31a9da7bdd748170bb9b5f82edaece754b4cf40b02b0c ganjoor-0.2.1.apk e473269044710813d2cf4119de663fe180f887239df7bdb1ccee0239ef84fd3e ganjoor-0.2.2.apk -d9c49f109854793a0d96a3bd42dffff931dc37825dc49b4ed80cc4de1349ff72 ganjoor-0.3.0.apk +5ac991ab8fe8676f89f4bc09a1a5d7464e32b6f74d789e7f29038b85f2c64f4a ganjoor-0.3.0.apk ``` Installing: `adb install -r releases/ganjoor-.apk`. A phone holding a *debug* build has diff --git a/releases/ganjoor-0.3.0.apk b/releases/ganjoor-0.3.0.apk index c1654b1..ba35dcf 100644 Binary files a/releases/ganjoor-0.3.0.apk and b/releases/ganjoor-0.3.0.apk differ